aboutsummaryrefslogtreecommitdiff
path: root/engines/lab/utils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/lab/utils.cpp')
-rw-r--r--engines/lab/utils.cpp413
1 files changed, 413 insertions, 0 deletions
diff --git a/engines/lab/utils.cpp b/engines/lab/utils.cpp
new file mode 100644
index 0000000000..9e057f8a70
--- /dev/null
+++ b/engines/lab/utils.cpp
@@ -0,0 +1,413 @@
+/* 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 "lab/lab.h"
+#include "lab/utils.h"
+
+namespace Lab {
+Utils::Utils(LabEngine *vm) : _vm(vm) {
+ _dataBytesPerRow = 0;
+}
+
+/*****************************************************************************/
+/* Scales the x co-ordinates to that of the new display. In the room parser */
+/* file, co-ordinates are set up on a 360x336 display. */
+/*****************************************************************************/
+uint16 Utils::scaleX(uint16 x) {
+ if (_vm->_isHiRes)
+ return (uint16)((x * 16) / 9);
+ else
+ return (uint16)((x * 8) / 9);
+}
+
+/*****************************************************************************/
+/* Scales the y co-ordinates to that of the new display. In the room parser */
+/* file, co-ordinates are set up on a 368x336 display. */
+/*****************************************************************************/
+uint16 Utils::scaleY(uint16 y) {
+ if (_vm->_isHiRes)
+ return (y + (y / 14));
+ else
+ return ((y * 10) / 24);
+}
+
+/*****************************************************************************/
+/* Scales the VGA cords to SVGA if necessary; otherwise, returns VGA cords. */
+/*****************************************************************************/
+int16 Utils::vgaScaleX(int16 x) {
+ if (_vm->_isHiRes)
+ return (x * 2);
+ else
+ return x;
+}
+
+/*****************************************************************************/
+/* Scales the VGA cords to SVGA if necessary; otherwise, returns VGA cords. */
+/*****************************************************************************/
+int16 Utils::vgaScaleY(int16 y) {
+ if (_vm->_isHiRes)
+ return ((y * 12) / 5);
+ else
+ return y;
+}
+
+uint16 Utils::svgaCord(uint16 cord) {
+ if (_vm->_isHiRes)
+ return cord;
+ else
+ return 0;
+}
+
+/*****************************************************************************/
+/* Converts SVGA cords to VGA if necessary, otherwise returns VGA cords. */
+/*****************************************************************************/
+int Utils::vgaUnscaleX(int x) {
+ if (_vm->_isHiRes)
+ return (x / 2);
+ else
+ return x;
+}
+
+/*****************************************************************************/
+/* Converts SVGA cords to VGA if necessary, otherwise returns VGA cords. */
+/*****************************************************************************/
+int Utils::vgaUnscaleY(int y) {
+ if (_vm->_isHiRes)
+ return ((y * 5) / 12);
+ else
+ return y;
+}
+
+/*****************************************************************************/
+/* Undiffs a piece of memory when header size is a byte, and copy/skip size */
+/* is also a byte. */
+/*****************************************************************************/
+void Utils::unDiffByteByte(byte *dest, byte *diff) {
+ uint16 skip, copy;
+
+ while (1) {
+ skip = *diff;
+ diff++;
+ copy = *diff;
+ diff++;
+
+ if (skip == 255) {
+ if (copy == 0) {
+ skip = READ_LE_UINT16(diff);
+ diff += 2;
+ copy = READ_LE_UINT16(diff);
+ diff += 2;
+ } else if (copy == 255)
+ return;
+ }
+
+ dest += skip;
+ memcpy(dest, diff, copy);
+ dest += copy;
+ diff += copy;
+ }
+}
+
+/*****************************************************************************/
+/* Undiffs a piece of memory when header size is a byte, and copy/skip size */
+/* is a word. */
+/*****************************************************************************/
+void Utils::unDiffByteWord(uint16 *dest, uint16 *diff) {
+ uint16 skip, copy;
+
+ while (1) {
+ skip = ((byte *)diff)[0];
+ copy = ((byte *)diff)[1];
+
+ diff++;
+
+ if (skip == 255) {
+ if (copy == 0) {
+ skip = READ_LE_UINT16(diff);
+ diff++;
+ copy = READ_LE_UINT16(diff);
+ diff++;
+ } else if (copy == 255)
+ return;
+ }
+
+ dest += skip;
+
+ while (copy > 3) {
+ *dest = READ_LE_UINT16(diff);
+ dest++;
+ diff++;
+
+ *dest = READ_LE_UINT16(diff);
+ dest++;
+ diff++;
+
+ *dest = READ_LE_UINT16(diff);
+ dest++;
+ diff++;
+
+ *dest = READ_LE_UINT16(diff);
+ dest++;
+ diff++;
+
+ copy -= 4;
+ }
+
+ while (copy) {
+ *dest = READ_LE_UINT16(diff);
+ dest++;
+ diff++;
+ copy--;
+ }
+ }
+}
+
+/*------------------------- unDiff Vertical Memory --------------------------*/
+
+/*****************************************************************************/
+/* Undiffs a piece of memory when header size is a byte, and copy/skip size */
+/* is a byte. */
+/*****************************************************************************/
+void Utils::VUnDiffByteByte(byte *dest, byte *diff, uint16 bytesPerRow) {
+ byte *curPtr;
+ uint16 skip, copy;
+ uint16 counter = 0;
+
+
+ while (counter < _dataBytesPerRow) {
+ curPtr = dest + counter;
+
+ for (;;) {
+ skip = *diff;
+ diff++;
+ copy = *diff;
+ diff++;
+
+ if (skip == 255) {
+ counter += copy;
+ break;
+ }
+
+ else {
+ curPtr += (skip * bytesPerRow);
+
+ while (copy) {
+ copy--;
+ *curPtr = *diff;
+ curPtr += bytesPerRow;
+ diff++;
+ }
+ }
+ }
+ }
+}
+
+/*****************************************************************************/
+/* Undiffs a piece of memory when header size is a byte, and copy/skip size */
+/* is a word. */
+/*****************************************************************************/
+void Utils::VUnDiffByteWord(uint16 *dest, uint16 *diff, uint16 bytesPerRow) {
+ uint16 *curPtr;
+ uint16 skip, copy;
+ uint16 counter = 0;
+
+ uint16 wordsPerRow = bytesPerRow / 2;
+
+ while (counter < (_dataBytesPerRow >> 1)) {
+ curPtr = dest + counter;
+
+ for (;;) {
+ skip = ((byte *)diff)[0];
+ copy = ((byte *)diff)[1];
+
+ diff++;
+
+
+ if (skip == 255) {
+ counter += copy;
+ break;
+ }
+
+ else {
+ curPtr += (skip * wordsPerRow);
+
+ while (copy) {
+ *curPtr = *diff; //swapUShort(*diff);
+ curPtr += wordsPerRow;
+ diff++;
+ copy--;
+ }
+ }
+ }
+ }
+}
+
+/*****************************************************************************/
+/* Undiffs a piece of memory when header size is a byte, and copy/skip size */
+/* is a long. */
+/*****************************************************************************/
+void Utils::VUnDiffByteLong(uint32 *dest, uint32 *diff, uint16 bytesPerRow) {
+ uint32 *_curPtr;
+ uint16 skip, copy;
+
+ uint16 counter = 0;
+ byte *diff1 = (byte *)diff;
+
+ uint16 longsperrow = bytesPerRow / 4;
+
+ while (counter < (_dataBytesPerRow >> 2)) {
+ _curPtr = dest + counter;
+
+ for (;;) {
+ skip = *diff1;
+ diff1++;
+
+ copy = *diff1;
+ diff1++;
+
+
+ if (skip == 255) {
+ counter += copy;
+ break;
+ }
+
+ else {
+ _curPtr += (skip * longsperrow);
+
+ while (copy) {
+ *_curPtr = *(uint32 *)diff1; //swapULong(*diff);
+ _curPtr += longsperrow;
+ diff1 += 4;
+ copy--;
+ }
+ }
+ }
+ }
+}
+
+/*****************************************************************************/
+/* Runlength decodes a chunk of memory. */
+/*****************************************************************************/
+void Utils::runLengthDecode(byte *dest, byte *source) {
+ int8 num;
+ int16 count;
+
+ while (1) {
+ num = (int8)*source;
+ source++;
+
+ if (num == 127) {
+ return;
+ } else if (num > '\0') {
+ memcpy(dest, source, num);
+ source += num;
+ dest += num;
+ } else {
+ count = (int16)(-num);
+ num = *source;
+ source++;
+
+ while (count) {
+ *dest = num;
+ dest++;
+ count--;
+ }
+ }
+ }
+}
+
+/*****************************************************************************/
+/* Does a vertical run length decode. */
+/*****************************************************************************/
+void Utils::VRunLengthDecode(byte *dest, byte *source, uint16 bytesPerRow) {
+ int8 num;
+ int16 count;
+ byte *top = dest;
+
+ for (uint16 i = 0; i < _dataBytesPerRow; i++) {
+ dest = top;
+ dest += i;
+
+ num = (int8)*source;
+ source++;
+
+ while (num != 127) {
+ if (num > '\0') {
+ while (num) {
+ *dest = *source;
+ source++;
+ dest += bytesPerRow;
+ num--;
+ }
+ } else {
+ count = (int16)(-num);
+ num = (int8)*source;
+ source++;
+
+ while (count) {
+ *dest = num;
+ dest += bytesPerRow;
+ count--;
+ }
+ }
+
+ num = *source;
+ source++;
+ }
+ }
+}
+
+/*****************************************************************************/
+/* Does the undiffing between the bitmaps. */
+/*****************************************************************************/
+void Utils::unDiff(byte *newBuf, byte *oldBuf, byte *diffData, uint16 bytesPerRow, bool isV) {
+ diffData++;
+ byte bufType = *diffData;
+ diffData++;
+
+ if (isV) {
+ if (bufType == 0)
+ VUnDiffByteByte(newBuf, diffData, bytesPerRow);
+ else if (bufType == 1)
+ VUnDiffByteWord((uint16 *)newBuf, (uint16 *)diffData, bytesPerRow);
+ else if (bufType == 3)
+ VUnDiffByteLong((uint32 *)newBuf, (uint32 *)diffData, bytesPerRow);
+ } else {
+ if (bufType == 0)
+ unDiffByteByte(newBuf, diffData);
+ else if (bufType == 1)
+ unDiffByteWord((uint16 *)newBuf, (uint16 *)diffData);
+ }
+}
+
+void Utils::setBytesPerRow(int num) {
+ _dataBytesPerRow = num;
+}
+} // End of namespace Lab