Exemple #1
0
void Control::parseTiltControl(ZVision *engine, Common::SeekableReadStream &stream) {
	RenderTable *renderTable = engine->getRenderManager()->getRenderTable();
	renderTable->setRenderState(RenderTable::TILT);

	// Loop until we find the closing brace
	Common::String line = stream.readLine();
	trimCommentsAndWhiteSpace(&line);

	while (!stream.eos() && !line.contains('}')) {
		if (line.matchString("angle*", true)) {
			float fov;
			sscanf(line.c_str(), "angle(%f)", &fov);
			renderTable->setTiltFoV(fov);
		} else if (line.matchString("linscale*", true)) {
			float scale;
			sscanf(line.c_str(), "linscale(%f)", &scale);
			renderTable->setTiltScale(scale);
		} else if (line.matchString("reversepana*", true)) {
			uint reverse;
			sscanf(line.c_str(), "reversepana(%u)", &reverse);
			if (reverse == 1) {
				renderTable->setTiltReverse(true);
			}
		}

		line = stream.readLine();
		trimCommentsAndWhiteSpace(&line);
	}

	renderTable->generateRenderTable();
}
PushToggleControl::PushToggleControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
		: Control(engine, key) {
	// Loop until we find the closing brace
	Common::String line = stream.readLine();
	trimCommentsAndWhiteSpace(&line);

	while (!stream.eos() && !line.contains('}')) {
		if (line.matchString("*_hotspot*", true)) {
			uint x;
			uint y;
			uint width;
			uint height;

			sscanf(line.c_str(), "%*[^(](%u,%u,%u,%u)", &x, &y, &width, &height);

			_hotspot = Common::Rect(x, y, x + width, y + height);
		} else if (line.matchString("cursor*", true)) {
			char nameBuffer[25];

			sscanf(line.c_str(), "%*[^(](%25[^)])", nameBuffer);

			_hoverCursor = Common::String(nameBuffer);
		}

		line = stream.readLine();
		trimCommentsAndWhiteSpace(&line);
	}

	if (_hotspot.isEmpty() || _hoverCursor.empty()) {
		warning("Push_toggle cursor %u was parsed incorrectly", key);
	}
}
LeverControl::LeverControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
		: Control(engine, key),
		  _frameInfo(0),
		  _frameCount(0),
		  _startFrame(0),
		  _currentFrame(0),
		  _lastRenderedFrame(0),
		  _mouseIsCaptured(false),
		  _isReturning(false),
		  _accumulatedTime(0),
		  _returnRoutesCurrentFrame(0) {

	// Loop until we find the closing brace
	Common::String line = stream.readLine();
	trimCommentsAndWhiteSpace(&line);

	while (!stream.eos() && !line.contains('}')) {
		if (line.matchString("*descfile*", true)) {
			char levFileName[25];
			sscanf(line.c_str(), "%*[^(](%25[^)])", levFileName);

			parseLevFile(levFileName);
		} else if (line.matchString("*cursor*", true)) {
			char cursorName[25];
			sscanf(line.c_str(), "%*[^(](%25[^)])", cursorName);

			_cursorName = Common::String(cursorName);
		}

		line = stream.readLine();
		trimCommentsAndWhiteSpace(&line);
	}

	renderFrame(_currentFrame);
}
void ScriptManager::parseScrFile(const Common::String &fileName, bool isGlobal) {
	Common::File file;
	if (!file.open(fileName)) {
		warning("Script file not found: %s", fileName.c_str());
		return;
	}

	while(!file.eos()) {
		Common::String line = file.readLine();
		if (file.err()) {
			warning("Error parsing scr file: %s", fileName.c_str());
			return;
		}

		trimCommentsAndWhiteSpace(&line);
		if (line.empty())
			continue;

		if (line.matchString("puzzle:*", true)) {
			Puzzle *puzzle = new Puzzle();
			sscanf(line.c_str(),"puzzle:%u",&(puzzle->key));

			parsePuzzle(puzzle, file);
			if (isGlobal) {
				_globalPuzzles.push_back(puzzle);
			} else {
				_activePuzzles.push_back(puzzle);
			}
		} else if (line.matchString("control:*", true)) {
			parseControl(line, file);
		}
	}
}
Exemple #5
0
SaveControl::SaveControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
	: Control(engine, key, CONTROL_SAVE),
	  _saveControl(false) {
	// Loop until we find the closing brace
	Common::String line = stream.readLine();
	_engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
	Common::String param;
	Common::String values;
	getParams(line, param, values);

	while (!stream.eos() && !line.contains('}')) {
		if (param.matchString("savebox", true)) {
			int saveId;
			int inputId;

			sscanf(values.c_str(), "%d %d", &saveId, &inputId);
			saveElement elmnt;
			elmnt.inputKey = inputId;
			elmnt.saveId = saveId;
			elmnt.exist = false;
			_inputs.push_back(elmnt);
		} else if (param.matchString("control_type", true)) {
			if (values.contains("save"))
				_saveControl = true;
			else
				_saveControl = false;
		}

		line = stream.readLine();
		_engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
		getParams(line, param, values);
	}

	for (saveElmntList::iterator iter = _inputs.begin(); iter != _inputs.end(); ++iter) {
		Control *ctrl = _engine->getScriptManager()->getControl(iter->inputKey);
		if (ctrl && ctrl->getType() == Control::CONTROL_INPUT) {
			InputControl *inp = (InputControl *)ctrl;
			inp->setReadOnly(!_saveControl);
			Common::SeekableReadStream *save = _engine->getSaveManager()->getSlotFile(iter->saveId);
			if (save) {
				SaveGameHeader header;
				if (_engine->getSaveManager()->readSaveGameHeader(save, header)) {
					inp->setText(header.saveName);
					iter->exist = true;
				}
				delete save;
			}
		}
	}
}
void ScriptManager::parsePuzzle(Puzzle *puzzle, Common::SeekableReadStream &stream) {
	Common::String line = stream.readLine();
	trimCommentsAndWhiteSpace(&line);

	while (!stream.eos() && !line.contains('}')) {
		if (line.matchString("criteria {", true)) {
			parseCriteria(stream, puzzle->criteriaList);
		} else if (line.matchString("results {", true)) {
			parseResults(stream, puzzle->resultActions);
		} else if (line.matchString("flags {", true)) {
			setStateFlags(puzzle->key, parseFlags(stream));
		}

		line = stream.readLine();
		trimCommentsAndWhiteSpace(&line);
	}
}
void FileBrowserDialog::normalieFileName() {
	Common::String filename = _fileName->getEditString();

	if (filename.matchString(_fileMask))
		return;

	_fileName->setEditString(filename + "." + _fileExt);
}
Exemple #8
0
InputControl::InputControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
		: Control(engine, key),
		  _nextTabstop(0),
		  _focused(false),
		  _textChanged(false),
		  _cursorOffset(0) {
	// Loop until we find the closing brace
	Common::String line = stream.readLine();
	trimCommentsAndWhiteSpace(&line);

	while (!stream.eos() && !line.contains('}')) {
		if (line.matchString("*rectangle*", true)) {
			int x1;
			int y1;
			int x2;
			int y2;

			sscanf(line.c_str(), "%*[^(](%d %d %d %d)", &x1, &y1, &x2, &y2);

			_textRectangle = Common::Rect(x1, y1, x2, y2);
		} else if (line.matchString("*aux_hotspot*", true)) {
			int x1;
			int y1;
			int x2;
			int y2;

			sscanf(line.c_str(), "%*[^(](%d %d %d %d)", &x1, &y1, &x2, &y2);

			_headerRectangle = Common::Rect(x1, y1, x2, y2);
		} else if (line.matchString("*string_init*", true)) {
			uint fontFormatNumber;

			sscanf(line.c_str(), "%*[^(](%u)", &fontFormatNumber);

			_textStyle = _engine->getStringManager()->getTextStyle(fontFormatNumber);
		} else if (line.matchString("*next_tabstop*", true)) {
			sscanf(line.c_str(), "%*[^(](%u)", &_nextTabstop);
		} else if (line.matchString("*cursor_animation*", true)) {
			char fileName[26];

			sscanf(line.c_str(), "%*[^(](%25s %*u)", fileName);

			_cursorAnimationFileName = Common::String(fileName);
		} else if (line.matchString("*cursor_dimensions*", true)) {
			// Ignore, use the dimensions in the animation file
		} else if (line.matchString("*cursor_animation_frames*", true)) {
			// Ignore, use the frame count in the animation file
		} else if (line.matchString("*focus*", true)) {
			_focused = true;
		}

		line = stream.readLine();
		trimCommentsAndWhiteSpace(&line);
	}
}
Exemple #9
0
LeverControl::LeverControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
	: Control(engine, key, CONTROL_LEVER),
	  _frameInfo(0),
	  _frameCount(0),
	  _startFrame(0),
	  _currentFrame(0),
	  _lastRenderedFrame(0),
	  _mouseIsCaptured(false),
	  _isReturning(false),
	  _accumulatedTime(0),
	  _returnRoutesCurrentFrame(0),
	  _animation(NULL),
	  _cursor(CursorIndex_Active),
	  _mirrored(false) {

	// Loop until we find the closing brace
	Common::String line = stream.readLine();
	_engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);

	Common::String param;
	Common::String values;
	getParams(line, param, values);

	while (!stream.eos() && !line.contains('}')) {
		if (param.matchString("descfile", true)) {
			char levFileName[25];
			sscanf(values.c_str(), "%24s", levFileName);

			parseLevFile(levFileName);
		} else if (param.matchString("cursor", true)) {
			char cursorName[25];
			sscanf(values.c_str(), "%24s", cursorName);

			_cursor = _engine->getCursorManager()->getCursorId(Common::String(cursorName));
		}

		line = stream.readLine();
		_engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
		getParams(line, param, values);
	}

	renderFrame(_currentFrame);
}
PushToggleControl::PushToggleControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
	: Control(engine, key, CONTROL_PUSHTGL),
	  _countTo(2),
	  _cursor(CursorIndex_Active),
	  _event(Common::EVENT_LBUTTONUP) {

	_hotspots.clear();

	// Loop until we find the closing brace
	Common::String line = stream.readLine();
	_engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
	Common::String param;
	Common::String values;
	getParams(line, param, values);

	while (!stream.eos() && !line.contains('}')) {
		if (param.matchString("*_hotspot", true)) {
			uint x;
			uint y;
			uint width;
			uint height;

			sscanf(values.c_str(), "%u,%u,%u,%u", &x, &y, &width, &height);

			_hotspots.push_back(Common::Rect(x, y, x + width + 1, y + height + 1));
		} else if (param.matchString("cursor", true)) {
			_cursor = _engine->getCursorManager()->getCursorId(values);
		} else if (param.matchString("animation", true)) {
			// Not used
		} else if (param.matchString("sound", true)) {
			// Not used
		} else if (param.matchString("count_to", true)) {
			sscanf(values.c_str(), "%u", &_countTo);
		} else if (param.matchString("mouse_event", true)) {
			if (values.equalsIgnoreCase("up")) {
				_event = Common::EVENT_LBUTTONUP;
			} else if (values.equalsIgnoreCase("down")) {
				_event = Common::EVENT_LBUTTONDOWN;
			} else if (values.equalsIgnoreCase("double")) {
				// Not used
			}
		} else if (param.matchString("venus_id", true)) {
			_venusId = atoi(values.c_str());
		}

		line = stream.readLine();
		_engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
		getParams(line, param, values);
	}

	if (_hotspots.size() == 0) {
		warning("Push_toggle %u was parsed incorrectly", key);
	}
}
Exemple #11
0
uint ScriptManager::parseFlags(Common::SeekableReadStream &stream) const {
	uint flags = 0;

	// Loop until we find the closing brace
	Common::String line = stream.readLine();
	trimCommentsAndWhiteSpace(&line);

	while (!stream.eos() && !line.contains('}')) {
		if (line.matchString("ONCE_PER_INST", true)) {
			flags |= ONCE_PER_INST;
		} else if (line.matchString("DO_ME_NOW", true)) {
			flags |= DO_ME_NOW;
		} else if (line.matchString("DISABLED", true)) {
			flags |= DISABLED;
		}

		line = stream.readLine();
		trimCommentsAndWhiteSpace(&line);
	}

	return flags;
}
Exemple #12
0
TitlerControl::TitlerControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
	: Control(engine, key, CONTROL_TITLER) {

	_surface = NULL;
	_curString = -1;

	// Loop until we find the closing brace
	Common::String line = stream.readLine();
	trimCommentsAndWhiteSpace(&line);
	Common::String param;
	Common::String values;
	getParams(line, param, values);

	while (!stream.eos() && !line.contains('}')) {
		if (param.matchString("string_resource_file", true)) {
			readStringsFile(values);
		} else if (param.matchString("rectangle", true)) {
			int x;
			int y;
			int x2;
			int y2;

			sscanf(values.c_str(), "%d %d %d %d", &x, &y, &x2, &y2);

			_rectangle = Common::Rect(x, y, x2, y2);
		}

		line = stream.readLine();
		trimCommentsAndWhiteSpace(&line);
		getParams(line, param, values);
	}

	if (!_rectangle.isEmpty()) {
		_surface = new Graphics::Surface;
		_surface->create(_rectangle.width(), _rectangle.height(), _engine->_pixelFormat);
		_surface->fillRect(Common::Rect(_surface->w, _surface->h), 0);
	}
}
Common::StringArray PAKSaveManager::listSavefiles(const Common::String &pattern) {
	PAKDIR *dirp = pakfs_opendir();
	pakfs_dirent *dp;
	Common::StringArray list;
	Common::String *fname;

	while ((dp = pakfs_readdir(dirp)) != NULL) {
		fname = new Common::String(dp->entryname);
		if (fname->matchString(pattern, false, false))
			list.push_back(dp->entryname);

		delete fname;
		free(dp);
	}

	pakfs_closedir(dirp);

	return list;
}
Exemple #14
0
InputControl::InputControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
	: Control(engine, key, CONTROL_INPUT),
	  _nextTabstop(0),
	  _focused(false),
	  _textChanged(false),
	  _cursorOffset(0),
	  _enterPressed(false),
	  _readOnly(false),
	  _txtWidth(0),
	  _animation(NULL) {
	// Loop until we find the closing brace
	Common::String line = stream.readLine();
	trimCommentsAndWhiteSpace(&line);
	Common::String param;
	Common::String values;
	getParams(line, param, values);

	while (!stream.eos() && !line.contains('}')) {
		if (param.matchString("rectangle", true)) {
			int x1;
			int y1;
			int x2;
			int y2;

			sscanf(values.c_str(), "%d %d %d %d", &x1, &y1, &x2, &y2);

			_textRectangle = Common::Rect(x1, y1, x2, y2);
		} else if (param.matchString("aux_hotspot", true)) {
			int x1;
			int y1;
			int x2;
			int y2;

			sscanf(values.c_str(), "%d %d %d %d", &x1, &y1, &x2, &y2);

			_headerRectangle = Common::Rect(x1, y1, x2, y2);
		} else if (param.matchString("string_init", true)) {
			uint fontFormatNumber;

			sscanf(values.c_str(), "%u", &fontFormatNumber);

			_stringInit.readAllStyle(_engine->getStringManager()->getTextLine(fontFormatNumber));
		} else if (param.matchString("chooser_init_string", true)) {
			uint fontFormatNumber;

			sscanf(values.c_str(), "%u", &fontFormatNumber);

			_stringChooserInit.readAllStyle(_engine->getStringManager()->getTextLine(fontFormatNumber));
		} else if (param.matchString("next_tabstop", true)) {
			sscanf(values.c_str(), "%u", &_nextTabstop);
		} else if (param.matchString("cursor_dimensions", true)) {
			// Ignore, use the dimensions in the animation file
		} else if (param.matchString("cursor_animation_frames", true)) {
			// Ignore, use the frame count in the animation file
		} else if (param.matchString("cursor_animation", true)) {
			char fileName[25];

			sscanf(values.c_str(), "%25s %*u", fileName);

			_animation = new MetaAnimation(fileName, _engine);
			_frame = -1;
			_frameDelay = 0;
		} else if (param.matchString("focus", true)) {
			_focused = true;
			_engine->getScriptManager()->setFocusControlKey(_key);
		} else if (param.matchString("venus_id", true)) {
			_venusId = atoi(values.c_str());
		}

		line = stream.readLine();
		trimCommentsAndWhiteSpace(&line);
		getParams(line, param, values);
	}
}
Exemple #15
0
void LeverControl::parseLevFile(const Common::String &fileName) {
	Common::File file;
	if (!file.open(fileName)) {
		warning("LEV file %s could could be opened", fileName.c_str());
		return;
	}

	Common::String line = file.readLine();

	while (!file.eos()) {
		if (line.matchString("*animation_id*", true)) {
			// Not used
		} else if (line.matchString("*filename*", true)) {
			char fileNameBuffer[25];
			sscanf(line.c_str(), "%*[^:]:%25[^~]~", fileNameBuffer);

			Common::String animationFileName(fileNameBuffer);

			if (animationFileName.hasSuffix(".avi")) {
				_animation.avi = new ZorkAVIDecoder();
				_animation.avi->loadFile(animationFileName);
				_fileType = AVI;
			} else if (animationFileName.hasSuffix(".rlf")) {
				_animation.rlf = new RlfAnimation(animationFileName, false);
				_fileType = RLF;
			}
		} else if (line.matchString("*skipcolor*", true)) {
			// Not used
		} else if (line.matchString("*anim_coords*", true)) {
			int left, top, right, bottom;
			sscanf(line.c_str(), "%*[^:]:%d %d %d %d~", &left, &top, &right, &bottom);

			_animationCoords.left = left;
			_animationCoords.top = top;
			_animationCoords.right = right;
			_animationCoords.bottom = bottom;
		} else if (line.matchString("*mirrored*", true)) {
			uint mirrored;
			sscanf(line.c_str(), "%*[^:]:%u~", &mirrored);

			_mirrored = mirrored == 0 ? false : true;
		} else if (line.matchString("*frames*", true)) {
			sscanf(line.c_str(), "%*[^:]:%u~", &_frameCount);

			_frameInfo = new FrameInfo[_frameCount];
		} else if (line.matchString("*elsewhere*", true)) {
			// Not used
		} else if (line.matchString("*out_of_control*", true)) {
			// Not used
		} else if (line.matchString("*start_pos*", true)) {
			sscanf(line.c_str(), "%*[^:]:%u~", &_startFrame);
			_currentFrame = _startFrame;
		} else if (line.matchString("*hotspot_deltas*", true)) {
			uint x;
			uint y;
			sscanf(line.c_str(), "%*[^:]:%u %u~", &x, &y);

			_hotspotDelta.x = x;
			_hotspotDelta.y = y;
		} else {
			uint frameNumber;
			uint x, y;

			if (sscanf(line.c_str(), "%u:%u %u", &frameNumber, &x, &y) == 3) {
				_frameInfo[frameNumber].hotspot.left = x;
				_frameInfo[frameNumber].hotspot.top = y;
				_frameInfo[frameNumber].hotspot.right = x + _hotspotDelta.x;
				_frameInfo[frameNumber].hotspot.bottom = y + _hotspotDelta.y;
			}

			Common::StringTokenizer tokenizer(line, " ^=()");
			tokenizer.nextToken();
			tokenizer.nextToken();

			Common::String token = tokenizer.nextToken();
			while (!tokenizer.empty()) {
				if (token == "D") {
					token = tokenizer.nextToken();

					uint angle;
					uint toFrame;
					sscanf(token.c_str(), "%u,%u", &toFrame, &angle);

					_frameInfo[frameNumber].directions.push_back(Direction(angle, toFrame));
				} else if (token.hasPrefix("P")) {
					// Format: P(<from> to <to>)
					tokenizer.nextToken();
					tokenizer.nextToken();
					token = tokenizer.nextToken();
					uint to = atoi(token.c_str());

					_frameInfo[frameNumber].returnRoute.push_back(to);
				}

				token = tokenizer.nextToken();
			}
		}

		line = file.readLine();
	}
}
Exemple #16
0
bool StyledTTFont::loadFont(const Common::String &fontName, int32 point) {
	Common::String newFontName;
	if (fontName.matchString("*times new roman*", true) || fontName.matchString("*times*", true)) {
		if ((_style & (STTF_BOLD | STTF_ITALIC)) == (STTF_BOLD | STTF_ITALIC))
			newFontName = "timesbi.ttf";
		else if (_style & STTF_BOLD)
			newFontName = "timesbd.ttf";
		else if (_style & STTF_ITALIC)
			newFontName = "timesi.ttf";
		else
			newFontName = "times.ttf";

	} else if (fontName.matchString("*courier new*", true) || fontName.matchString("*courier*", true) || fontName.matchString("*ZorkDeath*", true)) {
		if ((_style & (STTF_BOLD | STTF_ITALIC)) == (STTF_BOLD | STTF_ITALIC))
			newFontName = "courbi.ttf";
		else if (_style & STTF_BOLD)
			newFontName = "courbd.ttf";
		else if (_style & STTF_ITALIC)
			newFontName = "couri.ttf";
		else
			newFontName = "cour.ttf";

	} else if (fontName.matchString("*century schoolbook*", true)) {
		if ((_style & (STTF_BOLD | STTF_ITALIC)) == (STTF_BOLD | STTF_ITALIC))
			newFontName = "censcbkbi.ttf";
		else if (_style & STTF_BOLD)
			newFontName = "censcbkbd.ttf";
		else if (_style & STTF_ITALIC)
			newFontName = "censcbki.ttf";
		else
			newFontName = "censcbk.ttf";

	} else if (fontName.matchString("*garamond*", true)) {
		if ((_style & (STTF_BOLD | STTF_ITALIC)) == (STTF_BOLD | STTF_ITALIC))
			newFontName = "garabi.ttf";
		else if (_style & STTF_BOLD)
			newFontName = "garabd.ttf";
		else if (_style & STTF_ITALIC)
			newFontName = "garai.ttf";
		else
			newFontName = "gara.ttf";

	} else if (fontName.matchString("*arial*", true) || fontName.matchString("*ZorkNormal*", true)) {
		if ((_style & (STTF_BOLD | STTF_ITALIC)) == (STTF_BOLD | STTF_ITALIC))
			newFontName = "arialbi.ttf";
		else if (_style & STTF_BOLD)
			newFontName = "arialbd.ttf";
		else if (_style & STTF_ITALIC)
			newFontName = "ariali.ttf";
		else
			newFontName = "arial.ttf";

	} else {
		debug("Could not identify font: %s. Reverting to Arial", fontName.c_str());
		newFontName = "arial.ttf";
	}

	bool sharp = (_style & STTF_SHARP) == STTF_SHARP;

	Common::File *file = _engine->getSearchManager()->openFile(newFontName);

	if (!file) {
		Common::SeekableReadStream *themeFile = nullptr;
		if (ConfMan.hasKey("themepath")) {
			Common::FSNode themePath(ConfMan.get("themepath"));
			if (themePath.exists()) {
				Common::FSNode scummModern = themePath.getChild("scummmodern.zip");
				if (scummModern.exists()) {
					themeFile = scummModern.createReadStream();
				}
			}
		}
		if (!themeFile) { // Fallback : Search for ScummModern.zip in SearchMan.
			themeFile = SearchMan.createReadStreamForMember("scummmodern.zip");
		}
		if (themeFile) {
			Common::Archive *themeArchive = Common::makeZipArchive(themeFile);
			if (themeArchive->hasFile("FreeSans.ttf")) {
				Common::SeekableReadStream *stream = nullptr;
				stream = themeArchive->createReadStreamForMember("FreeSans.ttf");
				Graphics::Font *_newFont = Graphics::loadTTFFont(*stream, point, 60, (sharp ? Graphics::kTTFRenderModeMonochrome : Graphics::kTTFRenderModeNormal)); // 66 dpi for 640 x 480 on 14" display
				if (_newFont) {
					if (!_font)
						delete _font;
					_font = _newFont;
				}
				if (stream)
					delete stream;
			}
			delete themeArchive;
			themeArchive = nullptr;
		}
	} else {
		Graphics::Font *_newFont = Graphics::loadTTFFont(*file, point, 60, (sharp ? Graphics::kTTFRenderModeMonochrome : Graphics::kTTFRenderModeNormal)); // 66 dpi for 640 x 480 on 14" display
		if (_newFont) {
			if (!_font)
				delete _font;
			_font = _newFont;
		}
		delete file;
	}

	_fntName = fontName;
	_lineHeight = point;

	if (_font)
		return true;
	return false;
}
Exemple #17
0
void LeverControl::parseLevFile(const Common::String &fileName) {
	Common::File file;
	if (!_engine->getSearchManager()->openFile(file, fileName)) {
		warning("LEV file %s could could be opened", fileName.c_str());
		return;
	}

	Common::String line;
	Common::String param;
	Common::String values;

	while (!file.eos()) {
		line = file.readLine();
		getLevParams(line, param, values);

		if (param.matchString("animation_id", true)) {
			// Not used
		} else if (param.matchString("filename", true)) {
			_animation = _engine->loadAnimation(values);
		} else if (param.matchString("skipcolor", true)) {
			// Not used
		} else if (param.matchString("anim_coords", true)) {
			int left, top, right, bottom;
			sscanf(values.c_str(), "%d %d %d %d", &left, &top, &right, &bottom);

			_animationCoords.left = left;
			_animationCoords.top = top;
			_animationCoords.right = right;
			_animationCoords.bottom = bottom;
		} else if (param.matchString("mirrored", true)) {
			uint mirrored;
			sscanf(values.c_str(), "%u", &mirrored);

			_mirrored = mirrored == 0 ? false : true;
		} else if (param.matchString("frames", true)) {
			sscanf(values.c_str(), "%u", &_frameCount);

			_frameInfo = new FrameInfo[_frameCount];
		} else if (param.matchString("elsewhere", true)) {
			// Not used
		} else if (param.matchString("out_of_control", true)) {
			// Not used
		} else if (param.matchString("start_pos", true)) {
			sscanf(values.c_str(), "%u", &_startFrame);
			_currentFrame = _startFrame;
		} else if (param.matchString("hotspot_deltas", true)) {
			uint x;
			uint y;
			sscanf(values.c_str(), "%u %u", &x, &y);

			_hotspotDelta.x = x;
			_hotspotDelta.y = y;
		} else if (param.matchString("venus_id", true)) {
			_venusId = atoi(values.c_str());
		} else {
			uint frameNumber;
			uint x, y;

			line.toLowercase();

			if (sscanf(line.c_str(), "%u:%u %u", &frameNumber, &x, &y) == 3) {
				_frameInfo[frameNumber].hotspot.left = x;
				_frameInfo[frameNumber].hotspot.top = y;
				_frameInfo[frameNumber].hotspot.right = x + _hotspotDelta.x;
				_frameInfo[frameNumber].hotspot.bottom = y + _hotspotDelta.y;
			}

			Common::StringTokenizer tokenizer(line, " ^=()~");
			tokenizer.nextToken();
			tokenizer.nextToken();

			Common::String token = tokenizer.nextToken();
			while (!tokenizer.empty()) {
				if (token == "d") {
					token = tokenizer.nextToken();

					uint angle;
					uint toFrame;
					sscanf(token.c_str(), "%u,%u", &toFrame, &angle);

					_frameInfo[frameNumber].directions.push_back(Direction(angle, toFrame));
				} else if (token.hasPrefix("p")) {
					// Format: P(<from> to <to>)
					tokenizer.nextToken();
					tokenizer.nextToken();
					token = tokenizer.nextToken();
					uint to = atoi(token.c_str());

					_frameInfo[frameNumber].returnRoute.push_back(to);
				}

				token = tokenizer.nextToken();
			}
		}

		// Don't read lines in this place because last will not be parsed.
	}
}
Exemple #18
0
SlotControl::SlotControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
	: Control(engine, key, CONTROL_SLOT),
	  _cursor(CursorIndex_Active),
	  _distanceId('0') {

	_renderedItem = 0;
	_bkg = NULL;

	// Loop until we find the closing brace
	Common::String line = stream.readLine();
	_engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
	Common::String param;
	Common::String values;
	getParams(line, param, values);

	while (!stream.eos() && !line.contains('}')) {
		if (param.matchString("hotspot", true)) {
			int x;
			int y;
			int width;
			int height;

			sscanf(values.c_str(), "%d %d %d %d", &x, &y, &width, &height);

			_hotspot = Common::Rect(x, y, width, height);
		} else if (param.matchString("rectangle", true)) {
			int x;
			int y;
			int width;
			int height;

			sscanf(values.c_str(), "%d %d %d %d", &x, &y, &width, &height);

			_rectangle = Common::Rect(x, y, width, height);
		} else if (param.matchString("cursor", true)) {
			_cursor = _engine->getCursorManager()->getCursorId(values);
		} else if (param.matchString("distance_id", true)) {
			sscanf(values.c_str(), "%c", &_distanceId);
		} else if (param.matchString("venus_id", true)) {
			_venusId = atoi(values.c_str());
		} else if (param.matchString("eligible_objects", true)) {
			char buf[256];
			memset(buf, 0, 256);
			strncpy(buf, values.c_str(), 255);

			char *curpos = buf;
			char *strend = buf + strlen(buf);
			while (true) {
				char *st = curpos;

				if (st >= strend)
					break;

				while (*curpos != ' ' && curpos < strend)
					curpos++;

				*curpos = 0;
				curpos++;

				int obj = atoi(st);

				_eligibleObjects.push_back(obj);
			}
		}

		line = stream.readLine();
		_engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
		getParams(line, param, values);
	}

	if (_hotspot.isEmpty() || _rectangle.isEmpty()) {
		warning("Slot %u was parsed incorrectly", key);
	}
}
Exemple #19
0
void dumpEveryResultAction(const Common::String &destFile) {
	Common::HashMap<Common::String, byte> count;
	Common::HashMap<Common::String, bool> fileAlreadyUsed;

	Common::DumpFile output;
	output.open(destFile);

	// Find scr files
	Common::ArchiveMemberList list;
	SearchMan.listMatchingMembers(list, "*.scr");

	for (Common::ArchiveMemberList::iterator iter = list.begin(); iter != list.end(); ++iter) {
		Common::SeekableReadStream *stream = (*iter)->createReadStream();

		Common::String line = stream->readLine();
		trimCommentsAndWhiteSpace(&line);

		while (!stream->eos()) {
			if (line.matchString("*:add*", true)) {
				tryToDumpLine("add", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:animplay*", true)) {
				tryToDumpLine("animplay", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:animpreload*", true)) {
				tryToDumpLine("animpreload", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:animunload*", true)) {
				tryToDumpLine("animunload", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:attenuate*", true)) {
				tryToDumpLine("attenuate", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:assign*", true)) {
				tryToDumpLine("assign", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:change_location*", true)) {
				tryToDumpLine("change_location", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:crossfade*", true) && !fileAlreadyUsed["add"]) {
				tryToDumpLine("crossfade", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:debug*", true)) {
				tryToDumpLine("debug", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:delay_render*", true)) {
				tryToDumpLine("delay_render", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:disable_control*", true)) {
				tryToDumpLine("disable_control", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:disable_venus*", true)) {
				tryToDumpLine("disable_venus", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:display_message*", true)) {
				tryToDumpLine("display_message", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:dissolve*", true)) {
				tryToDumpLine("dissolve", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:distort*", true)) {
				tryToDumpLine("distort", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:enable_control*", true)) {
				tryToDumpLine("enable_control", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:flush_mouse_events*", true)) {
				tryToDumpLine("flush_mouse_events", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:inventory*", true)) {
				tryToDumpLine("inventory", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:kill*", true)) {
				tryToDumpLine("kill", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:menu_bar_enable*", true)) {
				tryToDumpLine("menu_bar_enable", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:music*", true)) {
				tryToDumpLine("music", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:pan_track*", true)) {
				tryToDumpLine("pan_track", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:playpreload*", true)) {
				tryToDumpLine("playpreload", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:preferences*", true)) {
				tryToDumpLine("preferences", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:quit*", true)) {
				tryToDumpLine("quit", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:random*", true)) {
				tryToDumpLine("random", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:region*", true)) {
				tryToDumpLine("region", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:restore_game*", true)) {
				tryToDumpLine("restore_game", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:rotate_to*", true)) {
				tryToDumpLine("rotate_to", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:save_game*", true)) {
				tryToDumpLine("save_game", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:set_partial_screen*", true)) {
				tryToDumpLine("set_partial_screen", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:set_screen*", true)) {
				tryToDumpLine("set_screen", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:set_venus*", true)) {
				tryToDumpLine("set_venus", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:stop*", true)) {
				tryToDumpLine("stop", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:streamvideo*", true)) {
				tryToDumpLine("streamvideo", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:syncsound*", true)) {
				tryToDumpLine("syncsound", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:timer*", true)) {
				tryToDumpLine("timer", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:ttytext*", true)) {
				tryToDumpLine("ttytext", line, &count, &fileAlreadyUsed, output);
			} else if (line.matchString("*:universe_music*", true)) {
				tryToDumpLine("universe_music", line, &count, &fileAlreadyUsed, output);
			}

			line = stream->readLine();
			trimCommentsAndWhiteSpace(&line);
		}

		for (Common::HashMap<Common::String, bool>::iterator fileUsedIter = fileAlreadyUsed.begin(); fileUsedIter != fileAlreadyUsed.end(); ++fileUsedIter) {
			fileUsedIter->_value = false;
		}
	}

	output.close();
}
Exemple #20
0
void ScriptManager::parseResults(Common::SeekableReadStream &stream, Common::List<ResultAction *> &actionList) const {
	// Loop until we find the closing brace
	Common::String line = stream.readLine();
	trimCommentsAndWhiteSpace(&line);

	// TODO: Re-order the if-then statements in order of highest occurrence
	while (!stream.eos() && !line.contains('}')) {
		if (line.empty()) {
			line = stream.readLine();
			trimCommentsAndWhiteSpace(&line);

			continue;
		}

		// Parse for the action type
		if (line.matchString("*:add*", true)) {
			actionList.push_back(new ActionAdd(line));
		} else if (line.matchString("*:animplay*", true)) {
			actionList.push_back(new ActionPlayAnimation(line));
		} else if (line.matchString("*:animpreload*", true)) {
			actionList.push_back(new ActionPreloadAnimation(line));
		} else if (line.matchString("*:animunload*", true)) {
			//actionList.push_back(new ActionUnloadAnimation(line));
		} else if (line.matchString("*:attenuate*", true)) {
			// TODO: Implement ActionAttenuate
		} else if (line.matchString("*:assign*", true)) {
			actionList.push_back(new ActionAssign(line));
		} else if (line.matchString("*:change_location*", true)) {
			actionList.push_back(new ActionChangeLocation(line));
		} else if (line.matchString("*:crossfade*", true)) {
			// TODO: Implement ActionCrossfade
		} else if (line.matchString("*:debug*", true)) {
			// TODO: Implement ActionDebug
		} else if (line.matchString("*:delay_render*", true)) {
			// TODO: Implement ActionDelayRender
		} else if (line.matchString("*:disable_control*", true)) {
			actionList.push_back(new ActionDisableControl(line));
		} else if (line.matchString("*:disable_venus*", true)) {
			// TODO: Implement ActionDisableVenus
		} else if (line.matchString("*:display_message*", true)) {
			// TODO: Implement ActionDisplayMessage
		} else if (line.matchString("*:dissolve*", true)) {
			// TODO: Implement ActionDissolve
		} else if (line.matchString("*:distort*", true)) {
			// TODO: Implement ActionDistort
		} else if (line.matchString("*:enable_control*", true)) {
			actionList.push_back(new ActionEnableControl(line));
		} else if (line.matchString("*:flush_mouse_events*", true)) {
			// TODO: Implement ActionFlushMouseEvents
		} else if (line.matchString("*:inventory*", true)) {
			// TODO: Implement ActionInventory
		} else if (line.matchString("*:kill*", true)) {
			// TODO: Implement ActionKill
		} else if (line.matchString("*:menu_bar_enable*", true)) {
			// TODO: Implement ActionMenuBarEnable
		} else if (line.matchString("*:music*", true)) {
			actionList.push_back(new ActionMusic(line));
		} else if (line.matchString("*:pan_track*", true)) {
			// TODO: Implement ActionPanTrack
		} else if (line.matchString("*:playpreload*", true)) {
			actionList.push_back(new ActionPlayPreloadAnimation(line));
		} else if (line.matchString("*:preferences*", true)) {
			// TODO: Implement ActionPreferences
		} else if (line.matchString("*:quit*", true)) {
			actionList.push_back(new ActionQuit());
		} else if (line.matchString("*:random*", true)) {
			actionList.push_back(new ActionRandom(line));
		} else if (line.matchString("*:region*", true)) {
			// TODO: Implement ActionRegion
		} else if (line.matchString("*:restore_game*", true)) {
			// TODO: Implement ActionRestoreGame
		} else if (line.matchString("*:rotate_to*", true)) {
			// TODO: Implement ActionRotateTo
		} else if (line.matchString("*:save_game*", true)) {
			// TODO: Implement ActionSaveGame
		} else if (line.matchString("*:set_partial_screen*", true)) {
			actionList.push_back(new ActionSetPartialScreen(line));
		} else if (line.matchString("*:set_screen*", true)) {
			actionList.push_back(new ActionSetScreen(line));
		} else if (line.matchString("*:set_venus*", true)) {
			// TODO: Implement ActionSetVenus
		} else if (line.matchString("*:stop*", true)) {
			// TODO: Implement ActionStop
		} else if (line.matchString("*:streamvideo*", true)) {
			actionList.push_back(new ActionStreamVideo(line));
		} else if (line.matchString("*:syncsound*", true)) {
			// TODO: Implement ActionSyncSound
		} else if (line.matchString("*:timer*", true)) {
			actionList.push_back(new ActionTimer(line));
		} else if (line.matchString("*:ttytext*", true)) {
			// TODO: Implement ActionTTYText
		} else if (line.matchString("*:universe_music*", true)) {
			// TODO: Implement ActionUniverseMusic
		} else if (line.matchString("*:copy_file*", true)) {
			// Not used. Purposely left empty
		} else {
			warning("Unhandled result action type: %s", line.c_str());
		}

		line = stream.readLine();
		trimCommentsAndWhiteSpace(&line);
	}

	return;
}
Exemple #21
0
bool StyledTTFont::loadFont(const Common::String &fontName, int32 point) {
	Common::String newFontName;
	Common::String freeFontName;
	Common::String liberationFontName;

	for (int i = 0; i < FONT_COUNT; i++) {
		FontStyle curFont = getSystemFont(i);
		if (fontName.matchString(curFont.zorkFont, true)) {
			newFontName = curFont.fontBase;
			freeFontName = curFont.freeFontBase;
			liberationFontName = curFont.liberationFontBase;

			if ((_style & STTF_BOLD) && (_style & STTF_ITALIC)) {
				newFontName += "bi";
				freeFontName += "Bold";
				freeFontName += curFont.freeFontItalicName;
				liberationFontName += "-BoldItalic";
			} else if (_style & STTF_BOLD) {
				newFontName += "bd";
				freeFontName += "Bold";
				liberationFontName += "-Bold";
			} else if (_style & STTF_ITALIC) {
				newFontName += "i";
				freeFontName += curFont.freeFontItalicName;
				liberationFontName += "-Italic";
			} else {
				liberationFontName += "-Regular";
			}

			newFontName += ".ttf";
			freeFontName += ".ttf";
			liberationFontName += ".ttf";
			break;
		}
	}

	if (newFontName.empty()) {
		debug("Could not identify font: %s. Reverting to Arial", fontName.c_str());
		newFontName = "arial.ttf";
		freeFontName = "FreeSans.ttf";
		liberationFontName = "LiberationSans-Regular.ttf";
	}

	bool sharp = (_style & STTF_SHARP) == STTF_SHARP;

	Common::File file;
	if (!file.open(newFontName) && !_engine->getSearchManager()->openFile(file, newFontName) &&
		!file.open(liberationFontName) && !_engine->getSearchManager()->openFile(file, liberationFontName) &&
		!file.open(freeFontName) && !_engine->getSearchManager()->openFile(file, freeFontName))
		error("Unable to open font file %s (Liberation Font alternative: %s, FreeFont alternative: %s)", newFontName.c_str(), liberationFontName.c_str(), freeFontName.c_str());

	Graphics::Font *_newFont = Graphics::loadTTFFont(file, point, 60, (sharp ? Graphics::kTTFRenderModeMonochrome : Graphics::kTTFRenderModeNormal)); // 66 dpi for 640 x 480 on 14" display
	if (_newFont) {
		if (!_font)
			delete _font;
		_font = _newFont;
	}

	_fntName = fontName;
	_lineHeight = point;

	if (_font)
		return true;
	return false;
}
Exemple #22
0
SafeControl::SafeControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
	: Control(engine, key, CONTROL_SAFE) {
	_statesCount = 0;
	_curState = 0;
	_animation = NULL;
	_innerRaduis = 0;
	_innerRadiusSqr = 0;
	_outerRadius = 0;
	_outerRadiusSqr = 0;
	_zeroPointer = 0;
	_startPointer = 0;
	_targetFrame = 0;

	// Loop until we find the closing brace
	Common::String line = stream.readLine();
	_engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
	Common::String param;
	Common::String values;
	getParams(line, param, values);

	while (!stream.eos() && !line.contains('}')) {
		if (param.matchString("animation", true)) {
			_animation = _engine->loadAnimation(values);
			_animation->start();
		} else if (param.matchString("rectangle", true)) {
			int x;
			int y;
			int width;
			int height;

			sscanf(values.c_str(), "%d %d %d %d", &x, &y, &width, &height);

			_rectangle = Common::Rect(x, y, width, height);
		} else if (param.matchString("num_states", true)) {
			_statesCount = atoi(values.c_str());
		} else if (param.matchString("center", true)) {
			int x;
			int y;

			sscanf(values.c_str(), "%d %d", &x, &y);
			_center = Common::Point(x, y);
		} else if (param.matchString("dial_inner_radius", true)) {
			_innerRaduis = atoi(values.c_str());
			_innerRadiusSqr = _innerRaduis * _innerRaduis;
		} else if (param.matchString("radius", true)) {
			_outerRadius = atoi(values.c_str());
			_outerRadiusSqr = _outerRadius * _outerRadius;
		} else if (param.matchString("zero_radians_offset", true)) {
			_zeroPointer = atoi(values.c_str());
		} else if (param.matchString("pointer_offset", true)) {
			_startPointer = atoi(values.c_str());
			_curState = _startPointer;
		} else if (param.matchString("cursor", true)) {
			// Not used
		} else if (param.matchString("mirrored", true)) {
			// Not used
		} else if (param.matchString("venus_id", true)) {
			_venusId = atoi(values.c_str());
		}

		line = stream.readLine();
		_engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
		getParams(line, param, values);
	}

	if (_animation)
		_animation->seekToFrame(_curState);
}
Exemple #23
0
PaintControl::PaintControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
    : Control(engine, key, CONTROL_PAINT) {

    _cursor = CursorIndex_Active;
    _paint = NULL;
    _bkg = NULL;
    _brush = NULL;
    _colorKey = 0;
    _mouseDown = false;

    // Loop until we find the closing brace
    Common::String line = stream.readLine();
    trimCommentsAndWhiteSpace(&line);
    Common::String param;
    Common::String values;
    getParams(line, param, values);

    while (!stream.eos() && !line.contains('}')) {
        if (param.matchString("rectangle", true)) {
            int x;
            int y;
            int width;
            int height;

            sscanf(values.c_str(), "%d %d %d %d", &x, &y, &width, &height);

            _rectangle = Common::Rect(x, y, width + x, height + y);
        } else if (param.matchString("cursor", true)) {
            _cursor = _engine->getCursorManager()->getCursorId(values);
        } else if (param.matchString("brush_file", true)) {
            _brush = _engine->getRenderManager()->loadImage(values, false);
        } else if (param.matchString("venus_id", true)) {
            _venusId = atoi(values.c_str());
        } else if (param.matchString("paint_file", true)) {
            _paint = _engine->getRenderManager()->loadImage(values, false);
        } else if (param.matchString("eligible_objects", true)) {
            char buf[256];
            memset(buf, 0, 256);
            strcpy(buf, values.c_str());

            char *curpos = buf;
            char *strend = buf + strlen(buf);
            while (true) {
                char *st = curpos;

                if (st >= strend)
                    break;

                while (*curpos != ' ' && curpos < strend)
                    curpos++;

                *curpos = 0;
                curpos++;

                int obj = atoi(st);

                _eligibleObjects.push_back(obj);
            }
        }

        line = stream.readLine();
        trimCommentsAndWhiteSpace(&line);
        getParams(line, param, values);
    }

    if (_paint) {
        _colorKey = _paint->format.RGBToColor(255, 0, 255);
        _bkg = new Graphics::Surface;
        _bkg->create(_rectangle.width(), _rectangle.height(), _paint->format);
        _bkg->fillRect(Common::Rect(_rectangle.width(), _rectangle.height()), _colorKey);

        Graphics::Surface *tmp = new Graphics::Surface;
        tmp->create(_rectangle.width(), _rectangle.height(), _paint->format);
        _engine->getRenderManager()->blitSurfaceToSurface(*_paint, _rectangle, *tmp, 0, 0);
        _paint->free();
        delete _paint;
        _paint = tmp;
    }
}
Exemple #24
0
TextChange TextStyleState::parseStyle(const Common::String &str, int16 len) {
	Common::String buf = Common::String(str.c_str(), len);

	uint retval = TEXT_CHANGE_NONE;

	Common::StringTokenizer tokenizer(buf, " ");
	Common::String token;

	while (!tokenizer.empty()) {
		token = tokenizer.nextToken();

		if (token.matchString("font", true)) {
			token = tokenizer.nextToken();
			if (token[0] == '"') {
				Common::String _tmp = Common::String(token.c_str() + 1);

				while (token.lastChar() != '"' && !tokenizer.empty()) {
					token = tokenizer.nextToken();
					_tmp += " " + token;
				}

				if (_tmp.lastChar() == '"')
					_tmp.deleteLastChar();

				_fontname = _tmp;
			} else {
				if (!tokenizer.empty())
					_fontname = token;
			}
			retval |= TEXT_CHANGE_FONT_TYPE;

		} else if (token.matchString("blue", true)) {
			if (!tokenizer.empty()) {
				token = tokenizer.nextToken();
				int32 tmp = atoi(token.c_str());
				if (_blue != tmp) {
					_blue = tmp;
					retval |= TEXT_CHANGE_FONT_STYLE;
				}
			}
		} else if (token.matchString("red", true)) {
			if (!tokenizer.empty()) {
				token = tokenizer.nextToken();
				int32 tmp = atoi(token.c_str());
				if (_red != tmp) {
					_red = tmp;
					retval |= TEXT_CHANGE_FONT_STYLE;
				}
			}
		} else if (token.matchString("green", true)) {
			if (!tokenizer.empty()) {
				token = tokenizer.nextToken();
				int32 tmp = atoi(token.c_str());
				if (_green != tmp) {
					_green = tmp;
					retval |= TEXT_CHANGE_FONT_STYLE;
				}
			}
		} else if (token.matchString("newline", true)) {
#if 0
			if ((retval & TXT_RET_NEWLN) == 0)
				_newline = 0;

			_newline++;
#endif
			retval |= TEXT_CHANGE_NEWLINE;
		} else if (token.matchString("point", true)) {
			if (!tokenizer.empty()) {
				token = tokenizer.nextToken();
				int32 tmp = atoi(token.c_str());
				if (_size != tmp) {
					_size = tmp;
					retval |= TEXT_CHANGE_FONT_TYPE;
				}
			}
		} else if (token.matchString("escapement", true)) {
			if (!tokenizer.empty()) {
				token = tokenizer.nextToken();
#if 0
				int32 tmp = atoi(token.c_str());
				_escapement = tmp;
#endif
			}
		} else if (token.matchString("italic", true)) {
			if (!tokenizer.empty()) {
				token = tokenizer.nextToken();
				if (token.matchString("on", true)) {
					if (_italic != true) {
						_italic = true;
						retval |= TEXT_CHANGE_FONT_STYLE;
					}
				} else if (token.matchString("off", true)) {
					if (_italic != false) {
						_italic = false;
						retval |= TEXT_CHANGE_FONT_STYLE;
					}
				}
			}
		} else if (token.matchString("underline", true)) {
			if (!tokenizer.empty()) {
				token = tokenizer.nextToken();
				if (token.matchString("on", true)) {
					if (_underline != true) {
						_underline = true;
						retval |= TEXT_CHANGE_FONT_STYLE;
					}
				} else if (token.matchString("off", true)) {
					if (_underline != false) {
						_underline = false;
						retval |= TEXT_CHANGE_FONT_STYLE;
					}
				}
			}
		} else if (token.matchString("strikeout", true)) {
			if (!tokenizer.empty()) {
				token = tokenizer.nextToken();
				if (token.matchString("on", true)) {
					if (_strikeout != true) {
						_strikeout = true;
						retval |= TEXT_CHANGE_FONT_STYLE;
					}
				} else if (token.matchString("off", true)) {
					if (_strikeout != false) {
						_strikeout = false;
						retval |= TEXT_CHANGE_FONT_STYLE;
					}
				}
			}
		} else if (token.matchString("bold", true)) {
			if (!tokenizer.empty()) {
				token = tokenizer.nextToken();
				if (token.matchString("on", true)) {
					if (_bold != true) {
						_bold = true;
						retval |= TEXT_CHANGE_FONT_STYLE;
					}
				} else if (token.matchString("off", true)) {
					if (_bold != false) {
						_bold = false;
						retval |= TEXT_CHANGE_FONT_STYLE;
					}
				}
			}
		} else if (token.matchString("skipcolor", true)) {
			if (!tokenizer.empty()) {
				token = tokenizer.nextToken();
#if 0
				if (token.matchString("on", true)) {
					_skipcolor = true;
				} else if (token.matchString("off", true)) {
					_skipcolor = false;
				}
#endif
			}
		} else if (token.matchString("image", true)) {
			// Not used
		} else if (token.matchString("statebox", true)) {
			if (!tokenizer.empty()) {
				token = tokenizer.nextToken();
				_statebox = atoi(token.c_str());
				retval |= TEXT_CHANGE_HAS_STATE_BOX;
			}
		} else if (token.matchString("justify", true)) {
			if (!tokenizer.empty()) {
				token = tokenizer.nextToken();
				if (token.matchString("center", true))
					_justification = TEXT_JUSTIFY_CENTER;
				else if (token.matchString("left", true))
					_justification = TEXT_JUSTIFY_LEFT;
				else if (token.matchString("right", true))
					_justification = TEXT_JUSTIFY_RIGHT;
			}
		}
	}
	return (TextChange)retval;
}