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 "titanic/star_control/star_field.h"
24 #include "titanic/star_control/surface_area.h"
25 #include "titanic/star_control/camera.h"
26 #include "titanic/titanic.h"
27 
28 namespace Titanic {
29 
CStarField()30 CStarField::CStarField() : _renderBoundaries(false), _renderConstMap(false), _mode(MODE_STARFIELD),
31 		_showBox(true), _closeToMarker(false), _isSolved(false) {
32 }
33 
load(SimpleFile * file)34 void CStarField::load(SimpleFile *file) {
35 	_markers.load(file);
36 	_crosshairs.load(file);
37 	_renderBoundaries = file->readNumber();
38 	_renderConstMap = file->readNumber();
39 	_mode = (StarMode)file->readNumber();
40 	_showBox = file->readNumber();
41 	_isSolved = file->readNumber();
42 }
43 
save(SimpleFile * file,int indent)44 void CStarField::save(SimpleFile *file, int indent) {
45 	_markers.save(file, indent);
46 	_crosshairs.save(file, indent);
47 	file->writeNumberLine(_renderBoundaries, indent);
48 	file->writeNumberLine(_renderConstMap, indent);
49 	file->writeNumberLine(_mode, indent);
50 	file->writeNumberLine(_showBox, indent);
51 	file->writeNumberLine(_isSolved, indent);
52 }
53 
initDocument()54 bool CStarField::initDocument() {
55 	bool valid = setup() && _constBounds.initialize();
56 	if (valid)
57 		valid = _starCloseup.setup();
58 	if (valid)
59 		valid = _constMap.initialize();
60 
61 	return valid;
62 }
63 
render(CVideoSurface * surface,CCamera * camera)64 void CStarField::render(CVideoSurface *surface, CCamera *camera) {
65 	CSurfaceArea surfaceArea(surface);
66 	draw(&surfaceArea, camera, &_starCloseup);
67 	if (_showBox)
68 		drawBox(&surfaceArea);
69 
70 	_markers.draw(&surfaceArea, camera, nullptr);
71 	_crosshairs.draw(&surfaceArea);
72 
73 	if (_renderConstMap)
74 		_constMap.draw(&surfaceArea, camera);
75 	if (_renderBoundaries)
76 		_constBounds.draw(&surfaceArea, camera);
77 
78 	renderLockLine(&surfaceArea, camera);
79 }
80 
getBoundaryState() const81 bool CStarField::getBoundaryState() const {
82 	return _renderBoundaries;
83 }
84 
setBoundaryState(bool state)85 void CStarField::setBoundaryState(bool state) {
86 	_renderBoundaries = state;
87 }
88 
getConstMapState() const89 bool CStarField::getConstMapState() const {
90 	return _renderConstMap;
91 }
92 
setConstMapState(bool state)93 void CStarField::setConstMapState(bool state) {
94 	_renderConstMap = state;
95 }
96 
get54() const97 int CStarField::get54() const {
98 	return _starCloseup.get4();
99 }
100 
set54(int val)101 void CStarField::set54(int val) {
102 	_starCloseup.set4(val);
103 }
104 
getMode() const105 StarMode CStarField::getMode() const {
106 	return _mode;
107 }
108 
setMode(StarMode mode)109 void CStarField::setMode(StarMode mode) {
110 	_mode = mode;
111 }
112 
toggleBox()113 void CStarField::toggleBox() {
114 	_showBox = !_showBox;
115 }
116 
setBoxVisible(bool isVisible)117 bool CStarField::setBoxVisible(bool isVisible) {
118 	bool oldVal = _showBox;
119 	_showBox = isVisible;
120 	return oldVal;
121 }
122 
getMatchedIndex() const123 int CStarField::getMatchedIndex() const {
124 	return _crosshairs._matchIndex;
125 }
126 
isCloseToMarker() const127 bool CStarField::isCloseToMarker() const {
128 	return _closeToMarker;
129 }
130 
setSolved()131 void CStarField::setSolved() {
132 	_isSolved = _crosshairs._matchIndex >= 2;
133 }
134 
isSolved() const135 bool CStarField::isSolved() const {
136 	return _isSolved;
137 }
138 
isSkipped() const139 bool CStarField::isSkipped() const {
140 	return _crosshairs.isSkipped();
141 }
142 
skipPuzzle()143 void CStarField::skipPuzzle() {
144 	_crosshairs._matchIndex = 3;
145 	setSolved();
146 }
147 
fn1(CErrorCode * errorCode)148 void CStarField::fn1(CErrorCode *errorCode) {
149 	_starCloseup.proc3(errorCode);
150 }
151 
drawBox(CSurfaceArea * surfaceArea)152 void CStarField::drawBox(CSurfaceArea *surfaceArea) {
153 	uint oldPixel = surfaceArea->_pixel;
154 	surfaceArea->_pixel = 0x323232;
155 	surfaceArea->setColorFromPixel();
156 
157 	surfaceArea->drawLine(FRect(202.60417, 63.75, 397.39584, 63.75));
158 	surfaceArea->drawLine(FRect(202.60417, 276.25, 397.39584, 276.25));
159 	surfaceArea->drawLine(FRect(193.75, 72.604164, 193.75, 267.39584));
160 	surfaceArea->drawLine(FRect(406.25, 72.604164, 406.25, 267.39584));
161 	surfaceArea->drawLine(FRect(202.60417, 63.75, 202.60417, 68.177086));
162 	surfaceArea->drawLine(FRect(397.39584, 63.75, 397.39584, 68.177086));
163 	surfaceArea->drawLine(FRect(202.60417, 276.25, 202.60417, 271.82291));
164 	surfaceArea->drawLine(FRect(397.39584, 276.25, 397.39584, 271.82291));
165 	surfaceArea->drawLine(FRect(193.75, 72.604164, 198.17708, 72.604164));
166 	surfaceArea->drawLine(FRect(193.75, 267.39584, 198.17708, 267.39584));
167 	surfaceArea->drawLine(FRect(406.25, 72.604164, 401.82291, 72.604164));
168 	surfaceArea->drawLine(FRect(406.25, 267.39584, 401.82291, 267.39584));
169 	surfaceArea->drawLine(FRect(300.0, 63.75, 300.0, 54.895832));
170 	surfaceArea->drawLine(FRect(300.0, 276.25, 300.0, 285.10416));
171 	surfaceArea->drawLine(FRect(193.75, 170.0, 184.89583, 170.0));
172 	surfaceArea->drawLine(FRect(406.25, 170.0, 415.10416, 170.0));
173 
174 	surfaceArea->_pixel = oldPixel;
175 	surfaceArea->setColorFromPixel();
176 }
177 
renderLockLine(CSurfaceArea * surfaceArea,CCamera * camera)178 void CStarField::renderLockLine(CSurfaceArea *surfaceArea, CCamera *camera) {
179 	FVector screenCoord, worldCoord, photoPos;
180 	_closeToMarker = false;
181 
182 	if (_mode == MODE_STARFIELD) {
183 		if (lockDistance(surfaceArea, camera, screenCoord, worldCoord, photoPos) > -1.0) {
184 			surfaceArea->_pixel = 0xA0A0;
185 			surfaceArea->setColorFromPixel();
186 			surfaceArea->drawLine(FRect(screenCoord._x, screenCoord._y, photoPos._x, photoPos._y));
187 		}
188 	}
189 }
190 
lockDistance(CSurfaceArea * surfaceArea,CCamera * camera,FVector & screenCoord,FVector & worldCoord,FVector & photoPos)191 double CStarField::lockDistance(CSurfaceArea *surfaceArea, CCamera *camera,
192 		FVector &screenCoord, FVector &worldCoord, FVector &photoPos) {
193 	if (_crosshairs.isEmpty())
194 		// No crosshairs selection yet
195 		return -1.0;
196 	if (_crosshairs._entryIndex == _crosshairs._matchIndex)
197 		// Trying to re-lock on a previously locked star
198 		return -1.0;
199 
200 	const CBaseStarEntry *dataP = _markers.getDataPtr(_crosshairs._entryIndex);
201 	worldCoord = dataP->_position;
202 	FVector tv = camera->getRelativePosNoCentering(2, worldCoord);
203 
204 	if (camera->getFrontClip() >= tv._z)
205 		return -1.0;
206 
207 	tv = camera->getRelativePos(2, tv);
208 
209 	screenCoord = FVector(tv._x + surfaceArea->_centroid._x,
210 		tv._y + surfaceArea->_centroid._y, tv._z);
211 	FPoint pt = _crosshairs.getPosition();
212 	photoPos = FVector(pt._x, pt._y, 1.0);
213 
214 	double incr = (screenCoord._x - pt._x) * (screenCoord._x - pt._x);
215 	if (incr > 3600.0)
216 		return -1.0;
217 
218 	incr += (screenCoord._y - pt._y) * (screenCoord._y - pt._y);
219 	if (incr > 3600.0)
220 		return -1.0;
221 
222 	_closeToMarker = true;
223 	return incr;
224 }
225 
fn6(CVideoSurface * surface,CCamera * camera)226 void CStarField::fn6(CVideoSurface *surface, CCamera *camera) {
227 	CSurfaceArea surfaceArea(surface);
228 	_crosshairs.fn1(this, &surfaceArea, camera);
229 }
230 
incLockLevel()231 void CStarField::incLockLevel() {
232 	_crosshairs.incMatches();
233 	setSolved();
234 }
235 
decLockLevel(CVideoSurface * surface)236 void CStarField::decLockLevel(CVideoSurface *surface) {
237 	_crosshairs.decMatches(surface, this, &_markers);
238 	setSolved();
239 }
240 
mouseButtonDown(CVideoSurface * surface,CCamera * camera,int flags,const Common::Point & pt)241 bool CStarField::mouseButtonDown(CVideoSurface *surface, CCamera *camera,
242 		int flags, const Common::Point &pt) {
243 	if (_mode == MODE_STARFIELD) {
244 		CSurfaceArea surfaceArea(surface);
245 		return selectStar(&surfaceArea, camera, pt);
246 	} else {
247 		int starNum = _crosshairs.indexOf(pt);
248 		if (starNum >= 0) {
249 			_crosshairs.selectStar(starNum, surface, this, &_markers);
250 			return true;
251 		}
252 
253 		return false;
254 	}
255 }
256 
getRandomStar() const257 const CBaseStarEntry *CStarField::getRandomStar() const {
258 	if (_data.empty())
259 		return nullptr;
260 
261 	return getDataPtr(g_vm->getRandomNumber(_data.size() - 1));
262 }
263 
getStar(int index) const264 const CBaseStarEntry *CStarField::getStar(int index) const {
265 	return (index < 0 || index >= (int)_data.size()) ? nullptr : getDataPtr(index);
266 }
267 
268 } // End of namespace Titanic
269