Example #1
0
/**
 * Load Sprite Bank
 */
int AnimationManager::loadSpriteBank(int idx, const Common::String &filename) {
	int result = 0;
	Bank[idx]._loadedFl = true;
	Bank[idx]._filename = filename;

	byte *fileDataPtr = _vm->_fileIO->loadFile(filename);

	Bank[idx]._fileHeader = 0;
	if (fileDataPtr[1] == 'L' && fileDataPtr[2] == 'E')
		Bank[idx]._fileHeader = 1;
	else if (fileDataPtr[1] == 'O' && fileDataPtr[2] == 'R')
		Bank[idx]._fileHeader = 2;

	if (!Bank[idx]._fileHeader) {
		_vm->_globals->freeMemory(fileDataPtr);
		Bank[idx]._loadedFl = false;
		result = -1;
	}

	Bank[idx]._data = fileDataPtr;

	int objectDataIdx = 0;
	for(objectDataIdx = 0; objectDataIdx <= 249; objectDataIdx++) {
		int width = _vm->_objectsMan->getWidth(fileDataPtr, objectDataIdx);
		int height = _vm->_objectsMan->getHeight(fileDataPtr, objectDataIdx);
		if (!width && !height)
			break;
	}

	if (objectDataIdx > 249) {
		_vm->_globals->freeMemory(fileDataPtr);
		Bank[idx]._loadedFl = false;
		result = -2;
	}
	Bank[idx]._objDataIdx = objectDataIdx;

	Common::String ofsFilename = Bank[idx]._filename;
	char ch;
	do {
		ch = ofsFilename.lastChar();
		ofsFilename.deleteLastChar();
	} while (ch != '.');
	ofsFilename += ".OFS";

	Common::File f;
	if (f.exists(ofsFilename)) {
		byte *ofsData = _vm->_fileIO->loadFile(ofsFilename);
		byte *curOfsData = ofsData;
		for (int objIdx = 0; objIdx < Bank[idx]._objDataIdx; ++objIdx, curOfsData += 8) {
			int x1 = READ_LE_INT16(curOfsData);
			int y1 = READ_LE_INT16(curOfsData + 2);
			int x2 = READ_LE_INT16(curOfsData + 4);
			int y2 = READ_LE_INT16(curOfsData + 6);

			_vm->_objectsMan->setOffsetXY(Bank[idx]._data, objIdx, x1, y1, 0);
			if (Bank[idx]._fileHeader == 2)
				_vm->_objectsMan->setOffsetXY(Bank[idx]._data, objIdx, x2, y2, 1);
		}

		_vm->_globals->freeMemory(ofsData);
		result = 0;
	}

	return result;
}
Example #2
0
// Box
void FontManager::box(int idx, int messageId, const Common::String &filename, int xp, int yp) {
	int textPosX = xp;
	if (idx < 0)
		error("Bad number for text");
	_fontFixedWidth = 11;

	_boxWidth = 11 * _text[idx]._length;
	if (_text[idx]._textLoadedFl) {
		int textType = _text[idx]._textType;
		if (textType != 6 && textType != 1 && textType != 3 && textType != 5) {
			int yCurrent = yp + 5;
			for (int lineNum = 0; lineNum < _text[idx]._lineCount; ++lineNum) {
				displayText(xp + 5, yCurrent, _text[idx]._lines[lineNum], _text[idx]._color);
				yCurrent += _fontFixedHeight + 1;
			}
		} else {
			int height = _text[idx]._height;
			int width = _text[idx]._width;
			_vm->_graphicsMan->restoreSurfaceRect(
				_vm->_graphicsMan->_frontBuffer,
				_text[idx]._textBlock,
				xp,
				yp,
				_text[idx]._width,
				_text[idx]._height);
			_vm->_graphicsMan->addDirtyRect(xp, yp, xp + width, yp + height);
		}
	} else {
		int lineCount = 0;
		for (int i = 0; i <= 19; i++)
			_textSortArray[i] = 0;

		_text[idx]._textLoadedFl = true;
		Common::String file = filename;
		if (strncmp(file.c_str(), _oldName.c_str(), strlen(file.c_str())) != 0) {
			// Starting to access a new file, so read in the index file for the file
			_oldName = file;
			_indexName = Common::String(file.c_str(), file.size() - 3);
			_indexName += "IND";

			Common::File f;
			if (!f.open(_indexName))
				error("Error opening file - %s", _indexName.c_str());
			int filesize = f.size();
			for (int i = 0; i < (filesize / 4); ++i)
				_index[i] = f.readUint32LE();
			f.close();
		}
		int bufSize;
		if (filename[0] != 'Z' || filename[1] != 'O') {
			Common::File f;
			if (!f.open(file))
				error("Error opening file - %s", _indexName.c_str());

			bufSize = 2048;
			f.seek(_index[messageId]);

			_tempText = _vm->_globals->allocMemory(2058);
			if (_tempText == NULL)
				error("Error allocating text");

			Common::fill(&_tempText[0], &_tempText[2058], 0);
			f.read(_tempText, 2048);
			f.close();
		} else {
			bufSize = 100;
			_tempText = _vm->_globals->allocMemory(110);
			Common::fill(&_tempText[0], &_tempText[110], 0);
			memcpy(_tempText, _zoneText + _index[messageId], 96);
			WRITE_LE_UINT16((uint16 *)_tempText + 48, READ_LE_INT16(_zoneText + _index[messageId] + 96));
		}
		byte *curTempTextPtr = _tempText;
		for (int i = 0; i < bufSize; i++) {
			byte curChar = *curTempTextPtr;
			if ((byte)(*curTempTextPtr + 46) > 27) {
				if ((byte)(curChar + 80) > 27) {
					if ((byte)(curChar - 65) <= 25 || (byte)(curChar - 97) <= 25)
						curChar = 32;
				} else {
					curChar -= 79;
				}
			} else {
				curChar += 111;
			}
			*curTempTextPtr = curChar;
			curTempTextPtr++;
		};

		int textLength;
		for (textLength = 0; textLength < bufSize; textLength++) {
			byte curChar = _tempText[textLength];
			if (curChar == '\r' || curChar == '\n') {
				_tempText[textLength] = 0;
				if (!_text[idx]._length)
					break;
			}
		}

		if (bufSize && bufSize > textLength) {
			_text[idx]._length = textLength;
			_boxWidth = 0;

			for (int curStrIdx = 0; curStrIdx < textLength + 1; curStrIdx++) {
				byte curChar = _tempText[curStrIdx];
				if (curChar <= 31)
					curChar = ' ';
				_boxWidth += _vm->_objectsMan->getWidth(_font, curChar - 32);
			}

			_boxWidth += 2;
			_text[idx]._pos.x = 320 - abs(_boxWidth / 2);
			textPosX = _vm->_events->_startPos.x + _text[idx]._pos.x;
			lineCount = 1;
			_text[idx]._lines[0] = Common::String((const char *)_tempText, textLength);
		} else {
			if (!_boxWidth)
				_boxWidth = 240;
			int tempTextIdx = 0;
			int lineSize;
			byte curChar;
			do {
				int curLineSize = 0;
				int ptrb = _boxWidth - 4;
				for (;;) {
					lineSize = curLineSize;
					do {
						curChar = _tempText[tempTextIdx + curLineSize++];
					} while (curChar != ' ' && curChar != '%');
					if (curLineSize >= ptrb / _fontFixedWidth) {
						if (curChar == '%')
							curChar = ' ';
						break;
					}
					if (curChar == '%') {
						lineSize = curLineSize;
						break;
					}
				}

				// WORKAROUND: Perhaps due to the usage of ScummVM strings here, recalculate what the
				// actual length of the line to be copied will be. Otherwise, you can see artifacts,
				// such as a single character beyond the end of string NULL.
				int actualSize = 0;
				while (actualSize < lineSize && _tempText[tempTextIdx + actualSize])
					++actualSize;

				_text[idx]._lines[lineCount] = Common::String((const char *)_tempText + tempTextIdx, actualSize);
				_textSortArray[lineCount++] = lineSize;

				tempTextIdx += lineSize;
			} while (curChar != '%');

			for (int i = 0; i <= 19; i++) {
				if (_textSortArray[i] <= 0) {
					_textSortArray[i] = 0;
				} else {
					int ptrc = 0;
					for (int curIdx = 0; curIdx < _textSortArray[i] - 1; curIdx++) {
						Common::String &line = _text[idx]._lines[i];
						byte curChar2 = (curIdx >= (int)line.size()) ? '\0' : line.c_str()[curIdx];
						if (curChar2 <= 31)
							curChar2 = ' ';
						ptrc += _vm->_objectsMan->getWidth(_font, (byte)curChar2 - 32);
					}
					_textSortArray[i] = ptrc;
				}
			}
			for (int i = 0; i <= 19; i++) {
				for (int j = i + 1; j != i; j = (j + 1) % 20) {
					if (_textSortArray[i] < _textSortArray[j])
						_textSortArray[i] = 0;
				}
			};

			for (int i = 0; i <= 19; i++) {
				if (_textSortArray[i])
					_boxWidth = _textSortArray[i];
			}

			if ((_text[idx]._textType < 2) || (_text[idx]._textType > 3)) {
				int i;
				for (i = xp - _vm->_events->_startPos.x; _boxWidth + i > 638 && i > -2 && _text[idx]._textType; i -= 2)
					;
				_text[idx]._pos.x = i;
				textPosX = _vm->_events->_startPos.x + i;
			} else {
				_text[idx]._pos.x = textPosX;
			}
		}
		int posX = textPosX;
		int posY = yp;
		int saveWidth = _boxWidth + 10;
		int saveHeight = (_fontFixedHeight + 1) * lineCount + 12;
		if (_text[idx]._textType == 6) {
			_text[idx]._pos.x = 315 - abs(saveWidth / 2);
			textPosX = posX = _vm->_events->_startPos.x + _text[idx]._pos.x;
			_text[idx]._pos.y = posY = 50;
		}
		int textType = _text[idx]._textType;
		if (textType == 1 || textType == 3 || textType == 5 || textType == 6) {
			int size = saveHeight * saveWidth;
			byte *ptrd = _vm->_globals->allocMemory(size);
			if (ptrd == NULL)
				error("Cutting a block for text box (%d)", size);

			_vm->_graphicsMan->copySurfaceRect(_vm->_graphicsMan->_frontBuffer, ptrd, posX, posY, saveWidth, saveHeight);
			_vm->_graphicsMan->fillSurface(ptrd, _vm->_graphicsMan->_colorTable, size);
			_vm->_graphicsMan->restoreSurfaceRect(_vm->_graphicsMan->_frontBuffer, ptrd, posX, posY, saveWidth, saveHeight);
			_vm->_globals->freeMemory(ptrd);

			_vm->_graphicsMan->drawHorizontalLine(_vm->_graphicsMan->_frontBuffer, posX, posY, saveWidth, (byte)-2);
			_vm->_graphicsMan->drawHorizontalLine(_vm->_graphicsMan->_frontBuffer, posX, saveHeight + posY, saveWidth, (byte)-2);
			_vm->_graphicsMan->drawVerticalLine(_vm->_graphicsMan->_frontBuffer, posX, posY, saveHeight, (byte)-2);
			_vm->_graphicsMan->drawVerticalLine(_vm->_graphicsMan->_frontBuffer, saveWidth + posX, posY, saveHeight, (byte)-2);
		}
		_text[idx]._lineCount = lineCount;
		int textPosY = posY + 5;

		for (int lineNum = 0; lineNum < lineCount; ++lineNum) {
			displayText(textPosX + 5, textPosY, _text[idx]._lines[lineNum], _text[idx]._color);
			textPosY += _fontFixedHeight + 1;
		}

		int blockWidth = saveWidth + 1;
		int blockHeight = saveHeight + 1;

		_text[idx]._width = blockWidth;
		_text[idx]._height = blockHeight;
		textType = _text[idx]._textType;
		if (textType == 6 || textType == 1 || textType == 3 || textType == 5) {
			_text[idx]._textBlock = _vm->_globals->freeMemory(_text[idx]._textBlock);
			int blockSize = blockHeight * blockWidth;
			byte *ptre = _vm->_globals->allocMemory(blockSize + 20);
			if (ptre == NULL)
				error("Cutting a block for text box (%d)", blockSize);

			_text[idx]._textBlock = ptre;
			_text[idx]._width = blockWidth;
			_text[idx]._height = blockHeight;
			_vm->_graphicsMan->copySurfaceRect(_vm->_graphicsMan->_frontBuffer, _text[idx]._textBlock, posX, posY, _text[idx]._width, blockHeight);
		}
		_tempText = _vm->_globals->freeMemory(_tempText);
	}
}