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