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 /*
24  * This file is based on WME Lite.
25  * http://dead-code.org/redir.php?target=wmelite
26  * Copyright (c) 2011 Jan Nedoma
27  */
28 
29 #include "engines/wintermute/ad/ad_region.h"
30 #include "engines/wintermute/base/base_dynamic_buffer.h"
31 #include "engines/wintermute/base/base_game.h"
32 #include "engines/wintermute/base/base_file_manager.h"
33 #include "engines/wintermute/base/base_parser.h"
34 #include "engines/wintermute/base/scriptables/script_value.h"
35 #include "engines/wintermute/base/scriptables/script.h"
36 
37 namespace Wintermute {
38 
IMPLEMENT_PERSISTENT(AdRegion,false)39 IMPLEMENT_PERSISTENT(AdRegion, false)
40 
41 //////////////////////////////////////////////////////////////////////////
42 AdRegion::AdRegion(BaseGame *inGame) : BaseRegion(inGame) {
43 	_blocked = false;
44 	_decoration = false;
45 	_zoom = 0;
46 	_alpha = 0xFFFFFFFF;
47 }
48 
49 
50 //////////////////////////////////////////////////////////////////////////
~AdRegion()51 AdRegion::~AdRegion() {
52 }
53 
getAlpha() const54 uint32 AdRegion::getAlpha() const {
55 	return _alpha;
56 }
57 
getZoom() const58 float AdRegion::getZoom() const {
59 	return _zoom;
60 }
61 
isBlocked() const62 bool AdRegion::isBlocked() const {
63 	return _blocked;
64 }
65 
hasDecoration() const66 bool AdRegion::hasDecoration() const {
67 	return _decoration;
68 }
69 
70 //////////////////////////////////////////////////////////////////////////
loadFile(const char * filename)71 bool AdRegion::loadFile(const char *filename) {
72 	char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
73 	if (buffer == nullptr) {
74 		_gameRef->LOG(0, "AdRegion::LoadFile failed for file '%s'", filename);
75 		return STATUS_FAILED;
76 	}
77 
78 	bool ret;
79 
80 	setFilename(filename);
81 
82 	if (DID_FAIL(ret = loadBuffer(buffer, true))) {
83 		_gameRef->LOG(0, "Error parsing REGION file '%s'", filename);
84 	}
85 
86 
87 	delete[] buffer;
88 
89 	return ret;
90 }
91 
92 
93 TOKEN_DEF_START
TOKEN_DEF(REGION)94 TOKEN_DEF(REGION)
95 TOKEN_DEF(TEMPLATE)
96 TOKEN_DEF(NAME)
97 TOKEN_DEF(ACTIVE)
98 TOKEN_DEF(ZOOM)
99 TOKEN_DEF(SCALE)
100 TOKEN_DEF(BLOCKED)
101 TOKEN_DEF(DECORATION)
102 TOKEN_DEF(POINT)
103 TOKEN_DEF(ALPHA_COLOR)
104 TOKEN_DEF(ALPHA)
105 TOKEN_DEF(EDITOR_SELECTED_POINT)
106 TOKEN_DEF(EDITOR_SELECTED)
107 TOKEN_DEF(SCRIPT)
108 TOKEN_DEF(CAPTION)
109 TOKEN_DEF(PROPERTY)
110 TOKEN_DEF(EDITOR_PROPERTY)
111 TOKEN_DEF_END
112 //////////////////////////////////////////////////////////////////////////
113 bool AdRegion::loadBuffer(char *buffer, bool complete) {
114 	TOKEN_TABLE_START(commands)
115 	TOKEN_TABLE(REGION)
116 	TOKEN_TABLE(TEMPLATE)
117 	TOKEN_TABLE(NAME)
118 	TOKEN_TABLE(ACTIVE)
119 	TOKEN_TABLE(ZOOM)
120 	TOKEN_TABLE(SCALE)
121 	TOKEN_TABLE(BLOCKED)
122 	TOKEN_TABLE(DECORATION)
123 	TOKEN_TABLE(POINT)
124 	TOKEN_TABLE(ALPHA_COLOR)
125 	TOKEN_TABLE(ALPHA)
126 	TOKEN_TABLE(EDITOR_SELECTED_POINT)
127 	TOKEN_TABLE(EDITOR_SELECTED)
128 	TOKEN_TABLE(SCRIPT)
129 	TOKEN_TABLE(CAPTION)
130 	TOKEN_TABLE(PROPERTY)
131 	TOKEN_TABLE(EDITOR_PROPERTY)
132 	TOKEN_TABLE_END
133 
134 	char *params;
135 	int cmd;
136 	BaseParser parser;
137 
138 	if (complete) {
139 		if (parser.getCommand(&buffer, commands, &params) != TOKEN_REGION) {
140 			_gameRef->LOG(0, "'REGION' keyword expected.");
141 			return STATUS_FAILED;
142 		}
143 		buffer = params;
144 	}
145 
146 	for (uint32 i = 0; i < _points.size(); i++) {
147 		delete _points[i];
148 	}
149 	_points.clear();
150 
151 	int ar = 255, ag = 255, ab = 255, alpha = 255;
152 
153 	while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
154 		switch (cmd) {
155 		case TOKEN_TEMPLATE:
156 			if (DID_FAIL(loadFile(params))) {
157 				cmd = PARSERR_GENERIC;
158 			}
159 			break;
160 
161 		case TOKEN_NAME:
162 			setName(params);
163 			break;
164 
165 		case TOKEN_CAPTION:
166 			setCaption(params);
167 			break;
168 
169 		case TOKEN_ACTIVE:
170 			parser.scanStr(params, "%b", &_active);
171 			break;
172 
173 		case TOKEN_BLOCKED:
174 			parser.scanStr(params, "%b", &_blocked);
175 			break;
176 
177 		case TOKEN_DECORATION:
178 			parser.scanStr(params, "%b", &_decoration);
179 			break;
180 
181 		case TOKEN_ZOOM:
182 		case TOKEN_SCALE: {
183 			int j;
184 			parser.scanStr(params, "%d", &j);
185 			_zoom = (float)j;
186 		}
187 		break;
188 
189 		case TOKEN_POINT: {
190 			int x, y;
191 			parser.scanStr(params, "%d,%d", &x, &y);
192 			_points.add(new BasePoint(x, y));
193 		}
194 		break;
195 
196 		case TOKEN_ALPHA_COLOR:
197 			parser.scanStr(params, "%d,%d,%d", &ar, &ag, &ab);
198 			break;
199 
200 		case TOKEN_ALPHA:
201 			parser.scanStr(params, "%d", &alpha);
202 			break;
203 
204 		case TOKEN_EDITOR_SELECTED:
205 			parser.scanStr(params, "%b", &_editorSelected);
206 			break;
207 
208 		case TOKEN_EDITOR_SELECTED_POINT:
209 			parser.scanStr(params, "%d", &_editorSelectedPoint);
210 			break;
211 
212 		case TOKEN_SCRIPT:
213 			addScript(params);
214 			break;
215 
216 		case TOKEN_PROPERTY:
217 			parseProperty(params, false);
218 			break;
219 
220 		case TOKEN_EDITOR_PROPERTY:
221 			parseEditorProperty(params, false);
222 			break;
223 		}
224 	}
225 	if (cmd == PARSERR_TOKENNOTFOUND) {
226 		_gameRef->LOG(0, "Syntax error in REGION definition");
227 		return STATUS_FAILED;
228 	}
229 
230 	createRegion();
231 
232 	_alpha = BYTETORGBA(ar, ag, ab, alpha);
233 
234 	return STATUS_OK;
235 }
236 
237 
238 //////////////////////////////////////////////////////////////////////////
239 // high level scripting interface
240 //////////////////////////////////////////////////////////////////////////
scCallMethod(ScScript * script,ScStack * stack,ScStack * thisStack,const char * name)241 bool AdRegion::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
242 	/*
243 	    //////////////////////////////////////////////////////////////////////////
244 	    // SkipTo
245 	    //////////////////////////////////////////////////////////////////////////
246 	    if (strcmp(name, "SkipTo")==0) {
247 	        stack->correctParams(2);
248 	        _posX = stack->pop()->getInt();
249 	        _posY = stack->pop()->getInt();
250 	        stack->pushNULL();
251 
252 	        return STATUS_OK;
253 	    }
254 
255 	    else*/ return BaseRegion::scCallMethod(script, stack, thisStack, name);
256 }
257 
258 
259 //////////////////////////////////////////////////////////////////////////
scGetProperty(const Common::String & name)260 ScValue *AdRegion::scGetProperty(const Common::String &name) {
261 	_scValue->setNULL();
262 
263 	//////////////////////////////////////////////////////////////////////////
264 	// Type
265 	//////////////////////////////////////////////////////////////////////////
266 	if (name == "Type") {
267 		_scValue->setString("ad region");
268 		return _scValue;
269 	}
270 
271 	//////////////////////////////////////////////////////////////////////////
272 	// Name
273 	//////////////////////////////////////////////////////////////////////////
274 	else if (name == "Name") {
275 		_scValue->setString(getName());
276 		return _scValue;
277 	}
278 
279 	//////////////////////////////////////////////////////////////////////////
280 	// Blocked
281 	//////////////////////////////////////////////////////////////////////////
282 	else if (name == "Blocked") {
283 		_scValue->setBool(_blocked);
284 		return _scValue;
285 	}
286 
287 	//////////////////////////////////////////////////////////////////////////
288 	// Decoration
289 	//////////////////////////////////////////////////////////////////////////
290 	else if (name == "Decoration") {
291 		_scValue->setBool(_decoration);
292 		return _scValue;
293 	}
294 
295 	//////////////////////////////////////////////////////////////////////////
296 	// Scale
297 	//////////////////////////////////////////////////////////////////////////
298 	else if (name == "Scale") {
299 		_scValue->setFloat(_zoom);
300 		return _scValue;
301 	}
302 
303 	//////////////////////////////////////////////////////////////////////////
304 	// AlphaColor
305 	//////////////////////////////////////////////////////////////////////////
306 	else if (name == "AlphaColor") {
307 		_scValue->setInt((int)_alpha);
308 		return _scValue;
309 	} else {
310 		return BaseRegion::scGetProperty(name);
311 	}
312 }
313 
314 
315 //////////////////////////////////////////////////////////////////////////
scSetProperty(const char * name,ScValue * value)316 bool AdRegion::scSetProperty(const char *name, ScValue *value) {
317 	//////////////////////////////////////////////////////////////////////////
318 	// Name
319 	//////////////////////////////////////////////////////////////////////////
320 	if (strcmp(name, "Name") == 0) {
321 		setName(value->getString());
322 		return STATUS_OK;
323 	}
324 
325 	//////////////////////////////////////////////////////////////////////////
326 	// Blocked
327 	//////////////////////////////////////////////////////////////////////////
328 	else if (strcmp(name, "Blocked") == 0) {
329 		_blocked = value->getBool();
330 		return STATUS_OK;
331 	}
332 
333 	//////////////////////////////////////////////////////////////////////////
334 	// Decoration
335 	//////////////////////////////////////////////////////////////////////////
336 	else if (strcmp(name, "Decoration") == 0) {
337 		_decoration = value->getBool();
338 		return STATUS_OK;
339 	}
340 
341 	//////////////////////////////////////////////////////////////////////////
342 	// Scale
343 	//////////////////////////////////////////////////////////////////////////
344 	else if (strcmp(name, "Scale") == 0) {
345 		_zoom = value->getFloat();
346 		return STATUS_OK;
347 	}
348 
349 	//////////////////////////////////////////////////////////////////////////
350 	// AlphaColor
351 	//////////////////////////////////////////////////////////////////////////
352 	else if (strcmp(name, "AlphaColor") == 0) {
353 		_alpha = (uint32)value->getInt();
354 		return STATUS_OK;
355 	} else {
356 		return BaseRegion::scSetProperty(name, value);
357 	}
358 }
359 
360 
361 //////////////////////////////////////////////////////////////////////////
scToString()362 const char *AdRegion::scToString() {
363 	return "[ad region]";
364 }
365 
366 
367 //////////////////////////////////////////////////////////////////////////
saveAsText(BaseDynamicBuffer * buffer,int indent)368 bool AdRegion::saveAsText(BaseDynamicBuffer *buffer, int indent) {
369 	buffer->putTextIndent(indent, "REGION {\n");
370 	buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", getName());
371 	buffer->putTextIndent(indent + 2, "CAPTION=\"%s\"\n", getCaption());
372 	buffer->putTextIndent(indent + 2, "BLOCKED=%s\n", _blocked ? "TRUE" : "FALSE");
373 	buffer->putTextIndent(indent + 2, "DECORATION=%s\n", _decoration ? "TRUE" : "FALSE");
374 	buffer->putTextIndent(indent + 2, "ACTIVE=%s\n", _active ? "TRUE" : "FALSE");
375 	buffer->putTextIndent(indent + 2, "SCALE=%d\n", (int)_zoom);
376 	buffer->putTextIndent(indent + 2, "ALPHA_COLOR { %d,%d,%d }\n", RGBCOLGetR(_alpha), RGBCOLGetG(_alpha), RGBCOLGetB(_alpha));
377 	buffer->putTextIndent(indent + 2, "ALPHA = %d\n", RGBCOLGetA(_alpha));
378 	buffer->putTextIndent(indent + 2, "EDITOR_SELECTED=%s\n", _editorSelected ? "TRUE" : "FALSE");
379 
380 	for (uint32 i = 0; i < _scripts.size(); i++) {
381 		buffer->putTextIndent(indent + 2, "SCRIPT=\"%s\"\n", _scripts[i]->_filename);
382 	}
383 
384 	if (_scProp) {
385 		_scProp->saveAsText(buffer, indent + 2);
386 	}
387 
388 	for (uint32 i = 0; i < _points.size(); i++) {
389 		buffer->putTextIndent(indent + 2, "POINT {%d,%d}\n", _points[i]->x, _points[i]->y);
390 	}
391 
392 	BaseClass::saveAsText(buffer, indent + 2);
393 
394 	buffer->putTextIndent(indent, "}\n\n");
395 
396 	return STATUS_OK;
397 }
398 
399 
400 //////////////////////////////////////////////////////////////////////////
persist(BasePersistenceManager * persistMgr)401 bool AdRegion::persist(BasePersistenceManager *persistMgr) {
402 	BaseRegion::persist(persistMgr);
403 
404 	persistMgr->transferUint32(TMEMBER(_alpha));
405 	persistMgr->transferBool(TMEMBER(_blocked));
406 	persistMgr->transferBool(TMEMBER(_decoration));
407 	persistMgr->transferFloat(TMEMBER(_zoom));
408 
409 	return STATUS_OK;
410 }
411 
412 } // End of namespace Wintermute
413