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
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (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, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #include "mads/mads.h"
24 #include "mads/camera.h"
25
26 namespace MADS {
27
Camera(MADSEngine * vm)28 Camera::Camera(MADSEngine *vm) : _vm(vm) {
29 _panAllowedFl = false;
30 _activeFl = false;
31 _currentFrameFl = false;
32 _manualFl = false;
33 _speed = -1;
34 _rate = -1;
35 _target = -1;
36 _distOffCenter = -1;
37 _startTolerance = -1;
38 _endTolerance = -1;
39 _direction = -1;
40 _timer = 0;
41 }
42
setDefaultPanX()43 void Camera::setDefaultPanX() {
44 _activeFl = false;
45 Scene &scene = _vm->_game->_scene;
46 _panAllowedFl = (scene._sceneInfo->_width > MADS_SCREEN_WIDTH);
47
48 if (_panAllowedFl) {
49 _manualFl = false;
50 _rate = 4;
51 _speed = 4;
52 _target = 0;
53 _distOffCenter = 80;
54 _startTolerance = 80;
55 _endTolerance = 4;
56 _timer = scene._frameStartTime;
57 }
58 }
59
setDefaultPanY()60 void Camera::setDefaultPanY() {
61 _activeFl = false;
62 Scene &scene = _vm->_game->_scene;
63 _panAllowedFl = (scene._sceneInfo->_height > MADS_SCENE_HEIGHT);
64
65 if (_panAllowedFl) {
66 _manualFl = true;
67 _rate = 4;
68 _speed = 2;
69 _target = 0;
70 _distOffCenter = 80;
71 _startTolerance = 60;
72 _endTolerance = 4;
73 _timer = scene._frameStartTime;
74 }
75 }
76
camPanTo(int target)77 void Camera::camPanTo(int target) {
78 if (_panAllowedFl) {
79 _activeFl = true;
80 _manualFl = true;
81 _target = target;
82 _timer = _vm->_game->_scene._frameStartTime;
83 }
84 }
85
camPan(int16 * picture_view,int16 * player_loc,int display_size,int picture_size)86 bool Camera::camPan(int16 *picture_view, int16 *player_loc, int display_size, int picture_size) {
87 bool panningFl = false;
88 if (_panAllowedFl) {
89 Scene &scene = _vm->_game->_scene;
90 Player &player = _vm->_game->_player;
91
92 _currentFrameFl = false;
93
94 uint32 timer;
95 if ((abs((int32) (_timer - player._priorTimer)) < _rate) && (player._ticksAmount == _rate))
96 timer = player._priorTimer;
97 else
98 timer = _timer;
99
100 if (_activeFl && (scene._frameStartTime < timer))
101 return (panningFl);
102
103 _timer = scene._frameStartTime + _rate;
104
105 if (_manualFl) {
106 if (_activeFl) {
107 int diff = _target - *picture_view;
108 int direction = 0;
109 if (diff < 0)
110 direction = -1;
111 else if (diff > 0)
112 direction = 1;
113
114 int magnitude = MIN(abs(diff), _speed);
115
116 if (magnitude == 0)
117 _activeFl = false;
118 else {
119 int panAmount;
120 if (direction < 0)
121 panAmount = -magnitude;
122 else
123 panAmount = magnitude;
124
125 *picture_view += panAmount;
126
127 panningFl = true;
128 _currentFrameFl = true;
129 }
130 }
131 } else {
132 if (!_activeFl) {
133 int lowEdge = *picture_view + _startTolerance;
134 int highEdge = *picture_view - _startTolerance + display_size - 1;
135
136 if ((*player_loc < lowEdge) && (*picture_view > 0)) {
137 _activeFl = true;
138 _direction = -1;
139 }
140
141 if ((*player_loc > highEdge) && (*picture_view < (picture_size - display_size))) {
142 _activeFl = true;
143 _direction = 1;
144 }
145 }
146
147 int newTarget = *player_loc - (display_size >> 1);
148
149 if (_direction < 0)
150 newTarget -= _distOffCenter;
151 else
152 newTarget += _distOffCenter;
153
154 newTarget = MAX(0, newTarget);
155 newTarget = MIN(newTarget, (picture_size - display_size));
156
157 _target = newTarget;
158
159 int diff = newTarget - *picture_view;
160 int magnitude = abs(diff);
161
162 int direction = 0;
163 if (diff < 0)
164 direction = -1;
165 else if (diff > 0)
166 direction = 1;
167
168 if (_activeFl && (magnitude <= _endTolerance))
169 _activeFl = false;
170
171 if (_activeFl) {
172 magnitude = MIN(magnitude, _speed);
173
174 int panAmount;
175 if (direction < 0)
176 panAmount = -magnitude;
177 else
178 panAmount = magnitude;
179
180 if (panAmount) {
181 *picture_view += panAmount;
182 panningFl = true;
183 _currentFrameFl = true;
184 }
185 }
186 }
187 }
188
189 return (panningFl);
190 }
191
192 } // End of namespace MADS
193