File: viewport.h

package info (click to toggle)
scummvm 2.9.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 450,580 kB
  • sloc: cpp: 4,299,825; asm: 28,322; python: 12,901; sh: 11,302; java: 9,289; xml: 7,895; perl: 2,639; ansic: 2,465; yacc: 1,670; javascript: 1,020; makefile: 933; lex: 578; awk: 275; objc: 82; sed: 11; php: 1
file content (226 lines) | stat: -rw-r--r-- 7,781 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
/* ScummVM - Graphic Adventure Engine
 *
 * ScummVM is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

//=============================================================================
//
// Definition for the game viewports and cameras.
//
//=============================================================================

#ifndef AGS_ENGINE_GAME_VIEWPORT_H
#define AGS_ENGINE_GAME_VIEWPORT_H

#include "common/std/memory.h"
#include "common/std/vector.h"
#include "ags/shared/util/geometry.h"
#include "ags/shared/util/scaling.h"

namespace AGS3 {

class Camera;
class Viewport;

typedef std::shared_ptr<Camera> PCamera;
typedef std::shared_ptr<Viewport> PViewport;
typedef std::weak_ptr<Camera> CameraRef;
typedef std::weak_ptr<Viewport> ViewportRef;

// TODO: move to utility header
// From https://stackoverflow.com/questions/45507041/how-to-check-if-weak-ptr-is-empty-non-assigned
// Tests that weak_ptr is empty (was not initialized with valid reference)
template <typename T>
bool is_uninitialized(std::weak_ptr<T> const &weak) {
	using wt = std::weak_ptr<T>;
	return !weak.owner_before(wt{}) &&!wt{} .owner_before(weak);
}


// Camera defines a "looking eye" inside the room, its position and size.
// It does not render anywhere on its own, instead it is linked to a viewport
// and latter draws what that camera sees.
// One camera may be linked to multiple viewports.
// Camera does not move on its own, this is performed by separate behavior
// algorithm. But it provides "lock" property that tells if its position is
// currently owned by user script.
class Camera {
public:
	// Gets camera ID (serves as an index)
	inline int GetID() const {
		return _id;
	}
	// Sets new camera ID
	void SetID(int id);
	// Returns Room camera position and size inside the room (in room coordinates)
	const Rect &GetRect() const;
	// Sets explicit room camera's orthographic size
	void SetSize(const Size sz);
	// Puts room camera to the new location in the room
	void SetAt(int x, int y);
	// Tells if camera is currently locked at custom position
	bool IsLocked() const;
	// Locks room camera at its current position
	void Lock();
	// Similar to SetAt, but also locks camera preventing it from following player character
	void LockAt(int x, int y);
	// Releases camera lock, letting it follow player character
	void Release();

	// Link this camera to a new viewport; this does not unlink any linked ones
	void LinkToViewport(ViewportRef viewport);
	// Unlinks this camera from a given viewport; does nothing if link did not exist
	void UnlinkFromViewport(int id);
	// Get the array of linked viewport references
	const std::vector<ViewportRef> &GetLinkedViewports() const;

	// Tell if this camera has changed recently
	inline bool HasChangedPosition() const {
		return _hasChangedPosition;
	}
	inline bool HasChangedSize() const {
		return _hasChangedSize;
	}
	// Clears the changed flags
	void ClearChangedFlags() {
		_hasChangedPosition = false;
		_hasChangedSize = false;
	}

private:
	int _id = -1;
	// Actual position and orthographic size
	Rect _position;
	// Locked or following player automatically
	bool _locked = false;
	// Linked viewport refs, used to notify viewports of camera changes
	std::vector<ViewportRef> _viewportRefs;
	// Flags that tell whether this camera's position on screen has changed recently
	bool _hasChangedPosition = false;
	bool _hasChangedSize = false;
};


// A result of coordinate conversion between screen and the room,
// tells which viewport was used to pass the "touch" through.
typedef std::pair<Point, int> VpPoint;


// Viewport class defines a rectangular area on game screen where the contents
// of a Camera are rendered.
// Viewport may have one linked camera at a time.
class Viewport {
public:
	// Gets viewport ID (serves as an index)
	inline int GetID() const {
		return _id;
	}
	// Sets new viewport ID
	void SetID(int id);
	// Returns viewport's position on screen
	inline const Rect &GetRect() const {
		return _position;
	}
	// Returns viewport's room-to-screen transformation
	inline const AGS::Shared::PlaneScaling &GetTransform() const {
		return _transform;
	}
	// Set viewport's rectangle on screen
	void SetRect(const Rect &rc);
	// Sets viewport size
	void SetSize(const Size sz);
	// Sets viewport's position on screen
	void SetAt(int x, int y);

	// Tells whether viewport content is rendered on screen
	bool IsVisible() const {
		return _visible;
	}
	// Changes viewport visibility
	void SetVisible(bool on);
	// Gets the order viewport is displayed on screen
	int GetZOrder() const {
		return _zorder;
	}
	// Sets the viewport's z-order on screen
	void SetZOrder(int zorder);

	// Calculates room-to-viewport coordinate conversion.
	void AdjustTransformation();
	// Returns linked camera
	PCamera GetCamera() const;
	// Links new camera to this viewport, overriding existing link;
	// pass nullptr to leave viewport without a camera link
	void LinkCamera(PCamera cam);

	// TODO: provide a Transform object here that does these conversions instead
	// Converts room coordinates to the game screen coordinates through this viewport;
	// if clipping is on, the function will fail for room coordinates outside of camera
	VpPoint RoomToScreen(int roomx, int roomy, bool clip = false) const;
	// Converts game screen coordinates to the room coordinates through this viewport;
	// if clipping is on, the function will fail for screen coordinates outside of viewport;
	// convert_cam_to_data parameter converts camera "game" coordinates to "data" units (legacy mode)
	VpPoint ScreenToRoom(int scrx, int scry, bool clip = false, bool convert_cam_to_data = false) const;

	// Following functions tell if this viewport has changed recently
	inline bool HasChangedPosition() const {
		return _hasChangedPosition;
	}
	inline bool HasChangedSize() const {
		return _hasChangedSize;
	}
	inline bool HasChangedVisible() const {
		return _hasChangedVisible;
	}
	inline void SetChangedVisible() {
		_hasChangedVisible = true;
	}
	// Clears the changed flags
	inline void ClearChangedFlags() {
		_hasChangedPosition = false;
		_hasChangedSize = false;
		_hasChangedVisible = false;
	}

private:
	// Parameterized implementation of screen-to-room coordinate conversion
	VpPoint ScreenToRoomImpl(int scrx, int scry, bool clip, bool convert_cam_to_data);

	int _id = -1;
	// Position of the viewport on screen
	Rect _position;
	// TODO: Camera reference (when supporting multiple cameras)
	// Coordinate transform between camera and viewport
	// TODO: need to add rotate conversion to let script API support that;
	// (maybe use full 3D matrix for that)
	AGS::Shared::PlaneScaling _transform;
	// Linked camera reference
	CameraRef _camera;
	bool _visible = true;
	int _zorder = 0;
	// Flags that tell whether this viewport's position on screen has changed recently
	bool _hasChangedPosition = false;
	bool _hasChangedOffscreen = false;
	bool _hasChangedSize = false;
	bool _hasChangedVisible = false;
};

} // namespace AGS3

#endif // AGS_ENGINE_AC_VIEWPORT_H