diff options
Diffstat (limited to 'engines/lab/utils.cpp')
-rw-r--r-- | engines/lab/utils.cpp | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/engines/lab/utils.cpp b/engines/lab/utils.cpp new file mode 100644 index 0000000000..957e996c03 --- /dev/null +++ b/engines/lab/utils.cpp @@ -0,0 +1,272 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* + * This code is based on Labyrinth of Time code with assistance of + * + * Copyright (c) 1993 Terra Nova Development + * Copyright (c) 2004 The Wyrmkeep Entertainment Co. + * + */ + +#include "common/file.h" + +#include "lab/lab.h" +#include "lab/utils.h" + +namespace Lab { +Utils::Utils(LabEngine *vm) : _vm(vm), _rnd("lab") { + _dataBytesPerRow = 0; +} + +uint16 Utils::scaleX(uint16 x) { + if (_vm->_isHiRes) + return (uint16)((x * 16) / 9); + else + return (uint16)((x * 8) / 9); +} + +uint16 Utils::scaleY(uint16 y) { + if (_vm->_isHiRes) + return (y + (y / 14)); + else + return ((y * 10) / 24); +} + +Common::Rect Utils::rectScale(int16 x1, int16 y1, int16 x2, int16 y2) { + return Common::Rect(scaleX(x1), scaleY(y1), scaleX(x2), scaleY(y2)); +} + +uint16 Utils::mapScaleX(uint16 x) { + if (_vm->_isHiRes) + return (x - 45); + else + return ((x - 45) >> 1); +} + +uint16 Utils::mapScaleY(uint16 y) { + if (_vm->_isHiRes) + return y; + else + return ((y - 35) >> 1) - (y >> 6); +} + +Common::Rect Utils::mapRectScale(int16 x1, int16 y1, int16 x2, int16 y2) { + return Common::Rect(mapScaleX(x1), mapScaleY(y1), mapScaleX(x2), mapScaleY(y2)); +} + +int16 Utils::vgaScaleX(int16 x) { + if (_vm->_isHiRes) + return (x * 2); + else + return x; +} + +int16 Utils::vgaScaleY(int16 y) { + if (_vm->_isHiRes) + return ((y * 12) / 5); + else + return y; +} + +Common::Rect Utils::vgaRectScale(int16 x1, int16 y1, int16 x2, int16 y2) { + return Common::Rect(vgaScaleX(x1), vgaScaleY(y1), vgaScaleX(x2), vgaScaleY(y2)); +} + +uint16 Utils::svgaCord(uint16 cord) { + if (_vm->_isHiRes) + return cord; + else + return 0; +} + +Common::Point Utils::vgaUnscale(Common::Point pos) { + Common::Point result; + if (_vm->_isHiRes) { + result.x = pos.x / 2; + result.y = (pos.y * 5) / 12; + } else + result = pos; + + return result; +} + +template<typename T> +void Utils::unDiff(T *dest, Common::File *sourceFile) { + byte bytesPerWord = sizeof(T); + + while (1) { + uint16 skip = sourceFile->readByte(); + uint16 copy = sourceFile->readByte(); + + if (skip == 255) { + if (copy == 0) { + skip = sourceFile->readUint16LE(); + copy = sourceFile->readUint16LE(); + } else if (copy == 255) + return; + } + + dest += skip; + + if (bytesPerWord == 1) { + sourceFile->read(dest, copy); + dest += copy; + } else { + while (copy) { + *dest = sourceFile->readUint16LE(); + dest++; + copy--; + } + } + } +} + +template<typename T> +void Utils::verticalUnDiff(T *dest, Common::File *sourceFile, uint16 bytesPerRow) { + uint16 counter = 0; + byte bytesPerWord = sizeof(T); + uint16 wordsPerRow = bytesPerRow / bytesPerWord; + + while (counter < wordsPerRow) { + T *curPtr = dest + counter; + + for (;;) { + uint16 skip = sourceFile->readByte(); + uint16 copy = sourceFile->readByte(); + + if (skip == 255) { + counter += copy; + break; + } else { + curPtr += (skip * wordsPerRow); + + while (copy) { + if (bytesPerWord == 1) + *curPtr = sourceFile->readByte(); + else if (bytesPerWord == 2) + *curPtr = sourceFile->readUint16LE(); + else if (bytesPerWord == 4) + *curPtr = sourceFile->readUint32LE(); + else + error("verticalUnDiff: Invalid bytesPerWord (%d)", bytesPerWord); + curPtr += wordsPerRow; + copy--; + } + } + } + } +} + +void Utils::runLengthDecode(byte *dest, Common::File *sourceFile) { + int8 num; + int16 count; + + while (1) { + num = sourceFile->readSByte(); + + if (num == 127) { + return; + } else if (num > '\0') { + sourceFile->read(dest, num); + dest += num; + } else { + count = (int16)(-num); + num = sourceFile->readSByte(); + + while (count) { + *dest = num; + dest++; + count--; + } + } + } +} + +void Utils::verticalRunLengthDecode(byte *dest, Common::File *sourceFile, uint16 bytesPerRow) { + int16 count; + byte *top = dest; + + for (int i = 0; i < _dataBytesPerRow; i++) { + dest = top; + dest += i; + + int8 num = sourceFile->readSByte(); + + while (num != 127) { + if (num > '\0') { + while (num) { + *dest = sourceFile->readByte(); + dest += bytesPerRow; + num--; + } + } else { + count = (int16)(-num); + num = sourceFile->readSByte(); + + while (count) { + *dest = num; + dest += bytesPerRow; + count--; + } + } + + num = sourceFile->readSByte(); + } + } +} + +void Utils::unDiff(byte *newBuf, byte *oldBuf, Common::File *sourceFile, uint16 bytesPerRow, bool isVertical) { + sourceFile->skip(1); + byte bufType = sourceFile->readByte(); + + if (isVertical) { + if (bufType == 0) + verticalUnDiff<byte>(newBuf, sourceFile, bytesPerRow); + else if (bufType == 1) + verticalUnDiff<uint16>((uint16 *)newBuf, sourceFile, bytesPerRow); + else if (bufType == 3) + verticalUnDiff<uint32>((uint32 *)newBuf, sourceFile, bytesPerRow); + else + error("Unexpected variable compression scheme %d", bufType); + } else { + if (bufType == 0) + unDiff<byte>(newBuf, sourceFile); + else if (bufType == 1) + unDiff<uint16>((uint16 *)newBuf, sourceFile); + else + error("Unexpected compression scheme %d", bufType); + } +} + +void Utils::setBytesPerRow(int num) { + _dataBytesPerRow = num; +} + +uint16 Utils::getRandom(uint16 max) { + if (max > 1) + return _rnd.getRandomNumber(max - 1); + else + return 0; +} + +} // End of namespace Lab |