aboutsummaryrefslogtreecommitdiff
path: root/engines/lab
diff options
context:
space:
mode:
authorStrangerke2015-12-01 20:10:42 +0100
committerWillem Jan Palenstijn2015-12-23 21:33:46 +0100
commitd656aa4859352e3d08e15346a482c943c1868502 (patch)
tree8810990fe5b132184c4224f7b702f8b0cfd73c43 /engines/lab
parent83d88cab8065613c71f91ce2b941b00192694ae1 (diff)
downloadscummvm-rg350-d656aa4859352e3d08e15346a482c943c1868502.tar.gz
scummvm-rg350-d656aa4859352e3d08e15346a482c943c1868502.tar.bz2
scummvm-rg350-d656aa4859352e3d08e15346a482c943c1868502.zip
LAB: Introduce the Anim class (WIP)
Diffstat (limited to 'engines/lab')
-rw-r--r--engines/lab/anim.cpp728
-rw-r--r--engines/lab/anim.h (renamed from engines/lab/diff.h)75
-rw-r--r--engines/lab/engine.cpp66
-rw-r--r--engines/lab/graphics.cpp75
-rw-r--r--engines/lab/intro.cpp40
-rw-r--r--engines/lab/lab.cpp7
-rw-r--r--engines/lab/lab.h3
-rw-r--r--engines/lab/labfun.h4
-rw-r--r--engines/lab/map.cpp2
-rw-r--r--engines/lab/module.mk2
-rw-r--r--engines/lab/processroom.cpp27
-rw-r--r--engines/lab/readdiff.cpp390
-rw-r--r--engines/lab/special.cpp40
-rw-r--r--engines/lab/undiff.cpp379
14 files changed, 931 insertions, 907 deletions
diff --git a/engines/lab/anim.cpp b/engines/lab/anim.cpp
new file mode 100644
index 0000000000..44d9eea5e8
--- /dev/null
+++ b/engines/lab/anim.cpp
@@ -0,0 +1,728 @@
+/* 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/endian.h"
+#include "lab/lab.h"
+
+namespace Lab {
+
+extern uint16 _dataBytesPerRow;
+extern BitMap *DrawBitMap;
+extern byte **startoffile;
+extern BitMap *DispBitMap;
+
+Anim::Anim(LabEngine *vm) : _vm(vm) {
+ header = 0;
+ CurBit = 0;
+ numchunks = 1;
+ IsBM = false;
+ headerdata._width = 0;
+ headerdata._height = 0;
+ headerdata._fps = 0;
+ headerdata._flags = 0;
+ WaitSec = 0;
+ WaitMicros = 0;
+ DelayMicros = 0;
+ continuous = false;
+ IsPlaying = false;
+ IsAnim = false;
+ IsPal = false;
+ nopalchange = false;
+ donepal = false;
+ framenumber = 0;
+ PlayOnce = false;
+ Buffer = nullptr;
+ storagefordifffile = nullptr;
+ difffile = &storagefordifffile;
+ size = 0;
+ RawDiffBM._bytesPerRow = 0;
+ RawDiffBM._flags = 0;
+ for (int i = 0; i < 16; i++)
+ RawDiffBM._planes[i] = nullptr;
+ RawDiffBM._rows = 0;
+ waitForEffect = false;
+ StopPlayingEnd = false;
+ samplespeed = 0;
+ DoBlack = false;
+ start = nullptr;
+ diffwidth = 0;
+ diffheight = 0;
+ stopsound = false;
+
+
+ for (int i = 0; i < 3 * 256; i++)
+ diffcmap[i] = 0;
+
+}
+
+/*------------------------ unDiff Horizontal Memory -------------------------*/
+
+/*****************************************************************************/
+/* Undiffs a piece of memory when header size is a byte, and copy/skip size */
+/* is also a byte. */
+/*****************************************************************************/
+static void 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. */
+/*****************************************************************************/
+static void 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--;
+ }
+ }
+}
+
+/*****************************************************************************/
+/* UnDiffs a coded DIFF string onto an already initialized piece of memory. */
+/*****************************************************************************/
+bool Anim::unDIFFMemory(byte *dest, byte *diff, uint16 headerSize, uint16 copySize) {
+ if (headerSize == 1) {
+ if (copySize == 1)
+ unDIFFByteByte(dest, diff);
+
+ else if (copySize == 2)
+ unDIFFByteWord((uint16 *)dest, (uint16 *)diff);
+
+ else
+ return false;
+ } else
+ error("unDIFFMemory: HeaderSize is %d", headerSize);
+
+ return true;
+}
+
+/*------------------------- unDiff Vertical Memory --------------------------*/
+
+/*****************************************************************************/
+/* Undiffs a piece of memory when header size is a byte, and copy/skip size */
+/* is a byte. */
+/*****************************************************************************/
+static void 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. */
+/*****************************************************************************/
+static void VUnDIFFByteWord(uint16 *Dest, uint16 *diff, uint16 bytesperrow) {
+ uint16 *CurPtr;
+ uint16 skip, copy;
+ uint16 counter = 0, wordsperrow;
+
+
+ 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. */
+/*****************************************************************************/
+static void VUnDIFFByteLong(uint32 *Dest, uint32 *diff, uint16 bytesperrow) {
+ uint32 *CurPtr;
+ uint16 skip, copy;
+ uint16 counter = 0, longsperrow;
+ byte *diff1 = (byte *)diff;
+
+
+ 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--;
+ }
+ }
+ }
+ }
+}
+
+/*****************************************************************************/
+/* UnDiffs a coded DIFF string onto an already initialized piece of memory. */
+/*****************************************************************************/
+bool Anim::VUnDIFFMemory(byte *Dest, byte *diff, uint16 HeaderSize, uint16 CopySize, uint16 bytesperrow) {
+ if (HeaderSize == 1) {
+ if (CopySize == 1)
+ VUnDIFFByteByte(Dest, diff, bytesperrow);
+
+ else if (CopySize == 2)
+ VUnDIFFByteWord((uint16 *)Dest, (uint16 *)diff, bytesperrow);
+
+ else if (CopySize == 4)
+ VUnDIFFByteLong((uint32 *)Dest, (uint32 *)diff, bytesperrow);
+
+ else
+ return false;
+ } else
+ return (false);
+
+ return true;
+}
+
+/*****************************************************************************/
+/* Runlength decodes a chunk of memory. */
+/*****************************************************************************/
+void Anim::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 Anim::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 Anim::unDiff(byte *NewBuf, byte *OldBuf, byte *DiffData, uint16 bytesperrow, bool IsV) {
+ byte buftype;
+
+ DiffData++;
+ buftype = *DiffData;
+ DiffData++;
+
+ if (IsV)
+ VUnDIFFMemory(NewBuf, DiffData, 1, buftype + 1, bytesperrow);
+ else
+ unDIFFMemory(NewBuf, DiffData, 1, buftype + 1);
+}
+
+void Anim::diffNextFrame() {
+ if (header == 65535) /* Already done. */
+ return;
+
+ if (DispBitMap->_flags & BITMAPF_VIDEO) {
+ DispBitMap->_planes[0] = g_lab->getCurrentDrawingBuffer();
+ DispBitMap->_planes[1] = DispBitMap->_planes[0] + 0x10000;
+ DispBitMap->_planes[2] = DispBitMap->_planes[1] + 0x10000;
+ DispBitMap->_planes[3] = DispBitMap->_planes[2] + 0x10000;
+ DispBitMap->_planes[4] = DispBitMap->_planes[3] + 0x10000;
+ }
+
+ _vm->_event->mouseHide();
+
+ while (1) {
+ if (CurBit >= numchunks) {
+ _vm->_event->mouseShow();
+
+ if (!IsBM) {
+ if (headerdata._fps) {
+ _vm->waitForTime(WaitSec, WaitMicros);
+ _vm->addCurTime(0L, DelayMicros, &WaitSec, &WaitMicros);
+ }
+
+ if (IsPal && !nopalchange) {
+ _vm->setPalette(diffcmap, 256);
+ IsPal = false;
+ }
+
+ donepal = true;
+ }
+
+ if (IsPal && !nopalchange && !IsBM && !donepal) {
+ _vm->setPalette(diffcmap, 256);
+ IsPal = false;
+ }
+
+ donepal = false;
+
+ framenumber++;
+
+ if ((framenumber == 1) && (continuous || (!PlayOnce)))
+ Buffer = *difffile;
+
+ IsAnim = (framenumber >= 3) && (!PlayOnce);
+ CurBit = 0;
+
+ if (DispBitMap->_flags & BITMAPF_VIDEO)
+ _vm->screenUpdate();
+
+ return; /* done with the next frame. */
+ }
+
+ _vm->_music->updateMusic();
+ header = READ_LE_UINT32(*difffile);
+ *difffile += 4;
+
+ size = READ_LE_UINT32(*difffile);
+ *difffile += 4;
+
+ switch (header) {
+ case 8L:
+ readBlock(diffcmap, size, difffile);
+ IsPal = true;
+ break;
+
+ case 10L:
+ RawDiffBM._planes[CurBit] = *difffile;
+
+ if (IsBM)
+ (*difffile) += size;
+ else {
+ readBlock(DrawBitMap->_planes[CurBit], size, difffile);
+ }
+
+ CurBit++;
+ break;
+
+ case 11L:
+ (*difffile) += 4;
+ runLengthDecode(DrawBitMap->_planes[CurBit], *difffile);
+ CurBit++;
+ (*difffile) += size - 4;
+ break;
+
+ case 12L:
+ (*difffile) += 4;
+ VRunLengthDecode(DrawBitMap->_planes[CurBit], *difffile, DrawBitMap->_bytesPerRow);
+ CurBit++;
+ (*difffile) += size - 4;
+ break;
+
+ case 20L:
+ unDiff(DrawBitMap->_planes[CurBit], DispBitMap->_planes[CurBit], *difffile, DrawBitMap->_bytesPerRow, false);
+ CurBit++;
+ (*difffile) += size;
+ break;
+
+ case 21L:
+ unDiff(DrawBitMap->_planes[CurBit], DispBitMap->_planes[CurBit], *difffile, DrawBitMap->_bytesPerRow, true);
+ CurBit++;
+ (*difffile) += size;
+ break;
+
+ case 25L:
+ CurBit++;
+ break;
+
+ case 26L:
+ CurBit++;
+ break;
+
+ case 30L:
+ case 31L: {
+ if (waitForEffect) {
+ while (_vm->_music->isSoundEffectActive()) {
+ _vm->_music->updateMusic();
+ _vm->waitTOF();
+ }
+ }
+
+ size -= 8L;
+
+
+ (*difffile) += 4;
+ samplespeed = READ_LE_UINT16(*difffile);
+ (*difffile) += 4;
+
+ byte *music = *difffile;
+ uint32 musicsize = size;
+ (*difffile) += size;
+
+ _vm->_music->playSoundEffect(samplespeed, musicsize, music);
+ break;
+ }
+ case 65535L:
+ if ((framenumber == 1) || PlayOnce || StopPlayingEnd) {
+ int didTOF = 0;
+
+ if (waitForEffect) {
+ while (_vm->_music->isSoundEffectActive()) {
+ _vm->_music->updateMusic();
+ _vm->waitTOF();
+
+ if (DispBitMap->_flags & BITMAPF_VIDEO)
+ didTOF = 1;
+ }
+ }
+
+ IsPlaying = false;
+ _vm->_event->mouseShow();
+
+ if (!didTOF)
+ _vm->screenUpdate();
+
+ return;
+ }
+
+ framenumber = 4; /* Random frame number so it never gets back to 2 */
+ *difffile = Buffer;
+ break;
+
+ default:
+ (*difffile) += size;
+ break;
+ }
+ }
+}
+
+/*****************************************************************************/
+/* A separate task launched by readDiff. Plays the DIFF. */
+/*****************************************************************************/
+void Anim::playDiff() {
+ WaitSec = 0L;
+ WaitMicros = 0L;
+ DelayMicros = 0L;
+ header = 0;
+ CurBit = 0;
+ framenumber = 0;
+ numchunks = 1;
+ donepal = false;
+ StopPlayingEnd = false;
+ difffile = &storagefordifffile;
+
+ IsPlaying = true;
+
+ if (DoBlack) {
+ DoBlack = false;
+ blackScreen();
+ }
+
+ start = *startoffile; /* Make a copy of the pointer to the start of the file */
+ *difffile = start; /* Now can modify the file without modifying the original */
+
+ if (start == NULL) {
+ IsPlaying = false;
+ return;
+ }
+
+ continuous = false;
+ uint32 signature = READ_BE_UINT32(*difffile);
+ (*difffile) += 4;
+
+ header = READ_LE_UINT32(*difffile);
+ (*difffile) += 4;
+
+ if ((signature != MKTAG('D', 'I', 'F', 'F')) || (header != 1219009121L)) {
+ IsPlaying = false;
+ return;
+ }
+
+ header = READ_LE_UINT32(*difffile);
+ (*difffile) += 4;
+
+ size = READ_LE_UINT32(*difffile);
+ (*difffile) += 4;
+
+ if (header == 0) {
+ // sizeof(headerdata) != 18, but the padding might be at the end
+ headerdata._version = READ_LE_UINT16(*difffile);
+ (*difffile) += 2;
+ headerdata._width = READ_LE_UINT16(*difffile);
+ (*difffile) += 2;
+ headerdata._height = READ_LE_UINT16(*difffile);
+ (*difffile) += 2;
+ headerdata._depth = *difffile[0];
+ (*difffile)++;
+ headerdata._fps = *difffile[0];
+ (*difffile)++;
+ headerdata._bufferSize = READ_LE_UINT32(*difffile);
+ (*difffile) += 4;
+ headerdata._machine = READ_LE_UINT16(*difffile);
+ (*difffile) += 2;
+ headerdata._flags = READ_LE_UINT32(*difffile);
+ (*difffile) += 4;
+
+ (*difffile) += size - 18;
+
+ continuous = CONTINUOUS & headerdata._flags;
+ diffwidth = headerdata._width;
+ diffheight = headerdata._height;
+ _dataBytesPerRow = diffwidth;
+
+ numchunks = (((int32) diffwidth) * diffheight) / 0x10000;
+
+ if ((uint32)(numchunks * 0x10000) < (uint32)(((int32) diffwidth) * diffheight))
+ numchunks++;
+ } else {
+ return;
+ }
+
+ for (header = 0; header < 8; header++)
+ RawDiffBM._planes[header] = NULL;
+
+ if (headerdata._fps)
+ DelayMicros = ONESECOND / headerdata._fps;
+
+ if (PlayOnce) {
+ while (header != 65535)
+ diffNextFrame();
+ } else
+ diffNextFrame();
+}
+
+/*****************************************************************************/
+/* Stops an animation from running. */
+/*****************************************************************************/
+void Anim::stopDiff() {
+ if (IsPlaying) {
+ if (IsAnim)
+ blackScreen();
+ }
+}
+
+/*****************************************************************************/
+/* Stops an animation from running. */
+/*****************************************************************************/
+void Anim::stopDiffEnd() {
+ if (IsPlaying) {
+ StopPlayingEnd = true;
+ while (IsPlaying) {
+ g_lab->_music->updateMusic();
+ diffNextFrame();
+ }
+ }
+}
+
+/*****************************************************************************/
+/* Stops the continuous sound from playing. */
+/*****************************************************************************/
+void Anim::stopSound() {
+ stopsound = true;
+}
+
+/*****************************************************************************/
+/* Reads in a DIFF file. */
+/*****************************************************************************/
+bool Anim::readDiff(bool playonce) {
+ PlayOnce = playonce;
+ playDiff();
+ return true;
+}
+
+} // End of namespace Lab
diff --git a/engines/lab/diff.h b/engines/lab/anim.h
index 4ff2059095..0472a72d7f 100644
--- a/engines/lab/diff.h
+++ b/engines/lab/anim.h
@@ -35,6 +35,8 @@
namespace Lab {
+class LabEngine;
+#define CONTINUOUS 0xFFFF
struct DIFFHeader {
uint16 _version; // unused
@@ -57,30 +59,63 @@ struct BitMap {
#define BITMAPF_NONE 0
#define BITMAPF_VIDEO (1<<7)
-/* unDiff.c */
-
-void initOffsets(uint16 bytesPerRow);
-
-bool unDIFFMemory(byte *dest, /* Where to Un-DIFF */
+class Anim {
+private:
+ LabEngine *_vm;
+
+ uint32 header;
+ uint16 CurBit;
+ uint16 numchunks;
+ uint32 WaitSec;
+ uint32 WaitMicros;
+ uint32 DelayMicros;
+ bool continuous;
+ bool IsPlaying;
+ bool IsAnim;
+ bool IsPal;
+ bool donepal;
+ uint16 framenumber;
+ bool PlayOnce;
+ byte *Buffer;
+ byte *storagefordifffile;
+ byte **difffile;
+ uint32 size;
+ bool StopPlayingEnd;
+ uint16 samplespeed;
+ byte *start;
+ uint32 diffwidth;
+ uint32 diffheight;
+ bool stopsound;
+
+public:
+ Anim(LabEngine *vm);
+
+ DIFFHeader headerdata;
+ char diffcmap[256 * 3];
+ bool IsBM; /* Just fill in the RawDIFFBM structure */
+ bool waitForEffect; /* Wait for each sound effect to finish before continuing. */
+ bool DoBlack; /* Black the screen before new picture */
+ bool nopalchange; /* Don't change the palette. */
+ BitMap RawDiffBM;
+
+ void unDiff(byte *NewBuf, byte *OldBuf, byte *DiffData, uint16 bytesperrow, bool IsV);
+ bool unDIFFMemory(byte *dest, /* Where to Un-DIFF */
byte *diff, /* The DIFFed code. */
uint16 headerSize, /* Size of header (1, 2 or 4 bytes) (only supports 1 currently */
uint16 copySize); /* Size of minimum copy or skip. (1, 2 or 4 bytes) */
-bool VUnDIFFMemory(byte *Dest, byte *diff, uint16 HeaderSize, uint16 CopySize, uint16 bytesperrow);
-void runLengthDecode(byte *Dest, byte *Source);
-void VRunLengthDecode(byte *Dest, byte *Source, uint16 bytesperrow);
-
-/* readDiff.c */
-
-void blackScreen();
-void blackAllScreen();
-void whiteScreen();
-bool readDiff(bool playonce);
-void diffNextFrame();
-void readSound(bool waitTillFinished, Common::File *file);
-void stopDiff();
-void stopDiffEnd();
-void stopSound();
+ bool VUnDIFFMemory(byte *dest, byte *diff, uint16 headerSize, uint16 copySize, uint16 bytesPerRow);
+ void runLengthDecode(byte *dest, byte *source);
+ void VRunLengthDecode(byte *dest, byte *source, uint16 bytesPerRow);
+ bool readDiff(bool playonce);
+ void diffNextFrame();
+ void readSound(bool waitTillFinished, Common::File *file);
+ void stopDiff();
+ void stopDiffEnd();
+ void stopSound();
+ void playDiff();
+
+};
} // End of namespace Lab
diff --git a/engines/lab/engine.cpp b/engines/lab/engine.cpp
index 4f44070c0d..3a7cd6f561 100644
--- a/engines/lab/engine.cpp
+++ b/engines/lab/engine.cpp
@@ -30,7 +30,7 @@
#include "lab/lab.h"
#include "lab/labfun.h"
-#include "lab/diff.h"
+#include "lab/anim.h"
#include "lab/text.h"
#include "lab/intro.h"
#include "lab/parsefun.h"
@@ -46,7 +46,7 @@ bool LongWinInFront = false;
TextFont *MsgFont;
-extern bool DoBlack, waitForEffect, stopsound, DoNotDrawMessage, nopalchange;
+extern bool stopsound, DoNotDrawMessage;
/* Global parser data */
@@ -446,17 +446,17 @@ static const char *getInvName(uint16 CurInv) {
else if (CurInv == WESTPAPERNUM) {
CurFileName = Inventory[CurInv].BInvName;
- nopalchange = true;
+ g_lab->_anim->nopalchange = true;
readPict(CurFileName, false);
- nopalchange = false;
+ g_lab->_anim->nopalchange = false;
doWestPaper();
}
else if (CurInv == NOTESNUM) {
CurFileName = Inventory[CurInv].BInvName;
- nopalchange = true;
+ g_lab->_anim->nopalchange = true;
readPict(CurFileName, false);
- nopalchange = false;
+ g_lab->_anim->nopalchange = false;
doNotes();
}
@@ -503,7 +503,7 @@ bool LabEngine::doUse(uint16 CurInv) {
if (CurInv == MAPNUM) { /* LAB: Labyrinth specific */
drawStaticMessage(kTextUseMap);
interfaceOff();
- stopDiff();
+ _anim->stopDiff();
CurFileName = " ";
CPtr = NULL;
doMap(_roomNum);
@@ -513,7 +513,7 @@ bool LabEngine::doUse(uint16 CurInv) {
} else if (CurInv == JOURNALNUM) { /* LAB: Labyrinth specific */
drawStaticMessage(kTextUseJournal);
interfaceOff();
- stopDiff();
+ _anim->stopDiff();
CurFileName = " ";
CPtr = NULL;
doJournal();
@@ -530,18 +530,18 @@ bool LabEngine::doUse(uint16 CurInv) {
_conditions->inclElement(LAMPON);
}
- DoBlack = false;
- waitForEffect = true;
+ _anim->DoBlack = false;
+ _anim->waitForEffect = true;
readPict("Music:Click", true);
- waitForEffect = false;
+ _anim->waitForEffect = false;
- DoBlack = false;
+ _anim->DoBlack = false;
Test = getInvName(CurInv);
} else if (CurInv == BELTNUM) { /* LAB: Labyrinth specific */
if (!_conditions->in(BELTGLOW))
_conditions->inclElement(BELTGLOW);
- DoBlack = false;
+ _anim->DoBlack = false;
Test = getInvName(CurInv);
} else if (CurInv == WHISKEYNUM) { /* LAB: Labyrinth specific */
_conditions->inclElement(USEDHELMET);
@@ -643,7 +643,7 @@ void LabEngine::mainGameLoop() {
if (GotMessage) {
if (QuitLab || g_engine->shouldQuit()) {
- stopDiff();
+ _anim->stopDiff();
break;
}
@@ -711,7 +711,7 @@ void LabEngine::mainGameLoop() {
GotMessage = false;
_music->checkRoomMusic();
_music->updateMusic();
- diffNextFrame();
+ _anim->diffNextFrame();
if (_followingCrumbs) {
int result = followCrumbs();
@@ -781,7 +781,7 @@ bool LabEngine::from_crumbs(uint32 tmpClass, uint16 code, uint16 Qualifier, Comm
uint16 NewDir;
- DoBlack = false;
+ _anim->DoBlack = false;
if ((msgClass == RAWKEY) && (!LongWinInFront)) {
if (code == 13) { /* The return key */
@@ -808,7 +808,7 @@ bool LabEngine::from_crumbs(uint32 tmpClass, uint16 code, uint16 Qualifier, Comm
if (Alternate) {
eatMessages();
Alternate = false;
- DoBlack = true;
+ _anim->DoBlack = true;
DoNotDrawMessage = false;
MainDisplay = true;
@@ -840,7 +840,7 @@ bool LabEngine::from_crumbs(uint32 tmpClass, uint16 code, uint16 Qualifier, Comm
if (curMsg == NULL) { /* Does music load and next animation frame when you've run out of messages */
_music->updateMusic();
- diffNextFrame();
+ _anim->diffNextFrame();
} else {
if (curMsg->msgClass == RAWKEY) {
if ((curMsg->code == 'Y') || (curMsg->code == 'y') || (curMsg->code == 'Q') || (curMsg->code == 'q')) {
@@ -856,7 +856,7 @@ bool LabEngine::from_crumbs(uint32 tmpClass, uint16 code, uint16 Qualifier, Comm
}
if (doit) {
- stopDiff();
+ _anim->stopDiff();
return false;
} else {
forceDraw = true;
@@ -887,7 +887,7 @@ bool LabEngine::from_crumbs(uint32 tmpClass, uint16 code, uint16 Qualifier, Comm
if ((actionMode == 4) && (gadgetId == 4) && (CPtr != NULL)) {
doMainView(&CPtr);
- DoBlack = true;
+ _anim->DoBlack = true;
HCPtr = NULL;
CPtr = NULL;
mayShowCrumbIndicator();
@@ -896,7 +896,7 @@ bool LabEngine::from_crumbs(uint32 tmpClass, uint16 code, uint16 Qualifier, Comm
eatMessages();
Alternate = true;
- DoBlack = true;
+ _anim->DoBlack = true;
DoNotDrawMessage = false;
interfaceOn(); /* Sets the correct gadget list */
@@ -957,7 +957,7 @@ bool LabEngine::from_crumbs(uint32 tmpClass, uint16 code, uint16 Qualifier, Comm
NewDir = Direction;
processArrow(&NewDir, gadgetId - 6);
doTurn(Direction, NewDir, &CPtr);
- DoBlack = true;
+ _anim->DoBlack = true;
Direction = NewDir;
forceDraw = true;
@@ -968,9 +968,9 @@ bool LabEngine::from_crumbs(uint32 tmpClass, uint16 code, uint16 Qualifier, Comm
if (doGoForward(&CPtr)) {
if (OldRoomNum == _roomNum)
- DoBlack = true;
+ _anim->DoBlack = true;
} else {
- DoBlack = true;
+ _anim->DoBlack = true;
processArrow(&Direction, gadgetId - 6);
if (OldRoomNum != _roomNum) {
@@ -979,7 +979,7 @@ bool LabEngine::from_crumbs(uint32 tmpClass, uint16 code, uint16 Qualifier, Comm
CurFileName = " ";
forceDraw = true;
} else {
- DoBlack = true;
+ _anim->DoBlack = true;
drawStaticMessage(kTextNoPath);
}
}
@@ -1030,12 +1030,12 @@ bool LabEngine::from_crumbs(uint32 tmpClass, uint16 code, uint16 Qualifier, Comm
}
}
} else if ((msgClass == GADGETUP) && Alternate) {
- DoBlack = true;
+ _anim->DoBlack = true;
if (gadgetId == 0) {
eatMessages();
Alternate = false;
- DoBlack = true;
+ _anim->DoBlack = true;
DoNotDrawMessage = false;
MainDisplay = true;
@@ -1050,7 +1050,7 @@ bool LabEngine::from_crumbs(uint32 tmpClass, uint16 code, uint16 Qualifier, Comm
if (gadgetId == 0) {
interfaceOff();
- stopDiff();
+ _anim->stopDiff();
CurFileName = " ";
doit = !saveRestoreGame();
@@ -1134,7 +1134,7 @@ bool LabEngine::from_crumbs(uint32 tmpClass, uint16 code, uint16 Qualifier, Comm
eatMessages();
Alternate = false;
- DoBlack = true;
+ _anim->DoBlack = true;
DoNotDrawMessage = false;
MainDisplay = true;
@@ -1202,7 +1202,7 @@ bool LabEngine::from_crumbs(uint32 tmpClass, uint16 code, uint16 Qualifier, Comm
drawStaticMessage(kTextNothing);
} else if (TempCPtr->GraphicName) {
if (*(TempCPtr->GraphicName)) {
- DoBlack = true;
+ _anim->DoBlack = true;
CPtr = TempCPtr;
} else if (curPos.y < (VGAScaleY(149) + SVGACord(2)))
drawStaticMessage(kTextNothing);
@@ -1253,7 +1253,7 @@ bool LabEngine::from_crumbs(uint32 tmpClass, uint16 code, uint16 Qualifier, Comm
} else if ((msgClass == MOUSEBUTTONS) && (IEQUALIFIER_RBUTTON & Qualifier)) {
eatMessages();
Alternate = !Alternate;
- DoBlack = true;
+ _anim->DoBlack = true;
DoNotDrawMessage = false;
MainDisplay = true;
interfaceOn(); /* Sets the correct gadget list */
@@ -1307,7 +1307,7 @@ void LabEngine::go() {
Intro intro;
intro.introSequence();
} else
- DoBlack = true;
+ _anim->DoBlack = true;
if (mem) {
_event->mouseShow();
@@ -1330,7 +1330,7 @@ void LabEngine::go() {
warning("STUB: waitForPress");
while (!1) { // 1 means ignore SDL_ProcessInput calls
_music->updateMusic();
- diffNextFrame();
+ _anim->diffNextFrame();
waitTOF();
}
}
diff --git a/engines/lab/graphics.cpp b/engines/lab/graphics.cpp
index 1adcb2dfe8..145ccb6bba 100644
--- a/engines/lab/graphics.cpp
+++ b/engines/lab/graphics.cpp
@@ -29,7 +29,7 @@
*/
#include "lab/lab.h"
-#include "lab/diff.h"
+#include "lab/anim.h"
#include "lab/parsetypes.h"
#include "lab/labfun.h"
#include "lab/parsefun.h"
@@ -41,12 +41,7 @@ namespace Lab {
BitMap bit1, bit2, *DispBitMap = &bit1, *DrawBitMap = &bit1;
-
-extern BitMap RawDiffBM;
-extern char diffcmap[256 * 3];
-extern bool IsBM, nopalchange;
-
-extern bool DoBlack, stopsound;
+extern bool stopsound;
extern TextFont *MsgFont;
extern const char *CurFileName;
@@ -54,12 +49,11 @@ extern const char *CurFileName;
/*------ From readPict.c. Reads in pictures and animations from disk. ------*/
/*---------------------------------------------------------------------------*/
-
/*****************************************************************************/
/* Reads in a picture into the dest bitmap. */
/*****************************************************************************/
bool readPict(const char *filename, bool playOnce) {
- stopDiff();
+ g_lab->_anim->stopDiff();
byte **file = g_lab->_music->newOpen(filename);
@@ -74,7 +68,7 @@ bool readPict(const char *filename, bool playOnce) {
DispBitMap->_rows = g_lab->_screenHeight;
DispBitMap->_flags = BITMAPF_VIDEO;
- readDiff(playOnce);
+ g_lab->_anim->readDiff(playOnce);
return true;
}
@@ -90,8 +84,8 @@ bool readMusic(const char *filename, bool waitTillFinished) {
if (!file)
return false;
- DoBlack = false;
- readSound(waitTillFinished, file);
+ g_lab->_anim->DoBlack = false;
+ g_lab->_anim->readSound(waitTillFinished, file);
return true;
}
@@ -102,7 +96,7 @@ bool readMusic(const char *filename, bool waitTillFinished) {
byte *readPictToMem(const char *filename, uint16 x, uint16 y) {
byte *mem;
- stopDiff();
+ g_lab->_anim->stopDiff();
allocFile((void **)&mem, (int32)x * (int32)y, "Bitmap");
byte *curMem = mem;
@@ -121,7 +115,7 @@ byte *readPictToMem(const char *filename, uint16 x, uint16 y) {
DispBitMap->_planes[3] = DispBitMap->_planes[2] + 0x10000;
DispBitMap->_planes[4] = DispBitMap->_planes[3] + 0x10000;
- readDiff(true);
+ g_lab->_anim->readDiff(true);
return mem;
}
@@ -437,9 +431,6 @@ void LabEngine::doScrollBlack() {
_event->mouseShow();
}
-extern BitMap RawDiffBM;
-extern DIFFHeader headerdata;
-
static void copyPage(uint16 width, uint16 height, uint16 nheight, uint16 startline, byte *mem) {
uint32 size, offSet, copysize;
uint16 curPage;
@@ -482,23 +473,23 @@ void LabEngine::doScrollWipe(char *filename) {
waitTOF();
}
- IsBM = true;
+ _anim->IsBM = true;
readPict(filename, true);
- setPalette(diffcmap, 256);
- IsBM = false;
- byte *mem = RawDiffBM._planes[0];
+ setPalette(_anim->diffcmap, 256);
+ _anim->IsBM = false;
+ byte *mem = _anim->RawDiffBM._planes[0];
_music->updateMusic();
uint16 by = VGAScaleX(3);
uint16 nheight = height;
- while (onrow < headerdata._height) {
+ while (onrow < _anim->headerdata._height) {
_music->updateMusic();
if ((by > nheight) && nheight)
by = nheight;
- if ((startline + by) > (headerdata._height - height - 1))
+ if ((startline + by) > (_anim->headerdata._height - height - 1))
break;
if (nheight)
@@ -544,10 +535,10 @@ void LabEngine::doScrollBounce() {
_event->mouseHide();
int width = VGAScaleX(320);
int height = VGAScaleY(149) + SVGACord(2);
- byte *mem = RawDiffBM._planes[0];
+ byte *mem = _anim->RawDiffBM._planes[0];
_music->updateMusic();
- int startline = headerdata._height - height - 1;
+ int startline = _anim->headerdata._height - height - 1;
for (int i = 0; i < 5; i++) {
_music->updateMusic();
@@ -628,7 +619,7 @@ void LabEngine::doTransWipe(CloseDataPtr *cPtr, char *filename) {
CurFileName = getPictName(cPtr);
byte *BitMapMem = readPictToMem(CurFileName, _screenWidth, lastY + 5);
- setPalette(diffcmap, 256);
+ setPalette(_anim->diffcmap, 256);
if (BitMapMem) {
imSource.Width = _screenWidth;
@@ -697,7 +688,37 @@ void LabEngine::doWipe(uint16 wipeType, CloseDataPtr *cPtr, char *filename) {
else if (wipeType == READFIRSTFRAME)
readPict(filename, false);
else if (wipeType == READNEXTFRAME)
- diffNextFrame();
+ _anim->diffNextFrame();
+}
+
+static byte blackbuffer[256 * 3];
+
+/*****************************************************************************/
+/* Changes the front screen to black. */
+/*****************************************************************************/
+void blackScreen() {
+ memset(blackbuffer, 0, 248 * 3);
+ g_lab->writeColorRegs(blackbuffer, 8, 248);
+
+ g_system->delayMillis(32);
+}
+
+/*****************************************************************************/
+/* Changes the front screen to white. */
+/*****************************************************************************/
+void whiteScreen() {
+ memset(blackbuffer, 255, 248 * 3);
+ g_lab->writeColorRegs(blackbuffer, 8, 248);
+}
+
+/*****************************************************************************/
+/* Changes the entire screen to black. */
+/*****************************************************************************/
+void blackAllScreen() {
+ memset(blackbuffer, 0, 256 * 3);
+ g_lab->writeColorRegs(blackbuffer, 0, 256);
+
+ g_system->delayMillis(32);
}
} // End of namespace Lab
diff --git a/engines/lab/intro.cpp b/engines/lab/intro.cpp
index e7f0187a73..a35984e623 100644
--- a/engines/lab/intro.cpp
+++ b/engines/lab/intro.cpp
@@ -32,13 +32,11 @@
#include "lab/intro.h"
#include "lab/labfun.h"
#include "lab/resource.h"
-#include "lab/diff.h"
+#include "lab/anim.h"
#include "lab/text.h"
#include "lab/interface.h"
namespace Lab {
-extern bool nopalchange, DoBlack;
-extern char diffcmap[256 * 3];
extern uint16 *FadePalette;
Intro::Intro() {
@@ -144,7 +142,7 @@ void Intro::doPictText(const char *filename, TextFont *msgFont, bool isscreen) {
if (msg == NULL) {
g_lab->_music->updateMusic();
- g_lab->diffNextFrame();
+ g_lab->_anim->diffNextFrame();
g_lab->getTime(&secs, &micros);
g_lab->anyTimeDiff(lastsecs, lastmicros, secs, micros, &secs, &micros);
@@ -239,8 +237,8 @@ void Intro::nReadPict(const char *filename, bool playOnce) {
if (_quitIntro)
return;
- DoBlack = _introDoBlack;
- stopDiffEnd();
+ g_lab->_anim->DoBlack = _introDoBlack;
+ g_lab->_anim->stopDiffEnd();
readPict(finalFileName.c_str(), playOnce);
}
@@ -256,7 +254,7 @@ void Intro::introSequence() {
0x0CB3, 0x0DC4, 0x0DD6, 0x0EE7
};
- DoBlack = true;
+ g_lab->_anim->DoBlack = true;
if (g_lab->getPlatform() != Common::kPlatformWindows) {
nReadPict("EA0", true);
@@ -278,12 +276,12 @@ void Intro::introSequence() {
g_lab->_music->initMusic();
- nopalchange = true;
+ g_lab->_anim->nopalchange = true;
if (g_lab->getPlatform() != Common::kPlatformWindows)
nReadPict("TNDcycle.pic", true);
else
nReadPict("TNDcycle2.pic", true);
- nopalchange = false;
+ g_lab->_anim->nopalchange = false;
FadePalette = palette;
@@ -291,9 +289,9 @@ void Intro::introSequence() {
if (_quitIntro)
break;
- palette[i] = ((diffcmap[i * 3] >> 2) << 8) +
- ((diffcmap[i * 3 + 1] >> 2) << 4) +
- (diffcmap[i * 3 + 2] >> 2);
+ palette[i] = ((g_lab->_anim->diffcmap[i * 3] >> 2) << 8) +
+ ((g_lab->_anim->diffcmap[i * 3 + 1] >> 2) << 4) +
+ (g_lab->_anim->diffcmap[i * 3 + 2] >> 2);
}
g_lab->_music->updateMusic();
@@ -348,14 +346,14 @@ void Intro::introSequence() {
TextFont *msgFont = g_lab->_resource->getFont("P:Map.fon");
- nopalchange = true;
+ g_lab->_anim->nopalchange = true;
nReadPict("Intro.1", true);
- nopalchange = false;
+ g_lab->_anim->nopalchange = false;
for (uint16 i = 0; i < 16; i++) {
- palette[i] = ((diffcmap[i * 3] >> 2) << 8) +
- ((diffcmap[i * 3 + 1] >> 2) << 4) +
- (diffcmap[i * 3 + 2] >> 2);
+ palette[i] = ((g_lab->_anim->diffcmap[i * 3] >> 2) << 8) +
+ ((g_lab->_anim->diffcmap[i * 3 + 1] >> 2) << 4) +
+ (g_lab->_anim->diffcmap[i * 3 + 2] >> 2);
}
doPictText("i.1", msgFont, true);
@@ -395,11 +393,11 @@ void Intro::introSequence() {
if (!_quitIntro)
for (uint16 i = 0; i < 50; i++) {
for (uint16 idx = (8 * 3); idx < (255 * 3); idx++)
- diffcmap[idx] = 255 - diffcmap[idx];
+ g_lab->_anim->diffcmap[idx] = 255 - g_lab->_anim->diffcmap[idx];
g_lab->_music->updateMusic();
g_lab->waitTOF();
- g_lab->setPalette(diffcmap, 256);
+ g_lab->setPalette(g_lab->_anim->diffcmap, 256);
g_lab->waitTOF();
g_lab->waitTOF();
}
@@ -438,7 +436,7 @@ void Intro::introSequence() {
nReadPict("Daed7", false);
doPictText("i.27", msgFont, false);
doPictText("i.28", msgFont, false);
- stopDiffEnd();
+ g_lab->_anim->stopDiffEnd();
nReadPict("Daed8", true);
doPictText("i.29", msgFont, false);
@@ -460,7 +458,7 @@ void Intro::introSequence() {
if (_quitIntro) {
g_lab->setAPen(0);
g_lab->rectFill(0, 0, g_lab->_screenWidth - 1, g_lab->_screenHeight - 1);
- DoBlack = true;
+ g_lab->_anim->DoBlack = true;
}
closeFont(msgFont);
diff --git a/engines/lab/lab.cpp b/engines/lab/lab.cpp
index 7ebfa8c3d3..a6fe4cf32c 100644
--- a/engines/lab/lab.cpp
+++ b/engines/lab/lab.cpp
@@ -38,14 +38,14 @@
#include "engines/dialogs.h"
#include "engines/engine.h"
#include "engines/util.h"
-
#include "gui/message.h"
+#include "engines/advancedDetector.h"
#include "lab/lab.h"
#include "lab/labfun.h"
#include "lab/resource.h"
+#include "lab/anim.h"
-#include "engines/advancedDetector.h"
namespace Lab {
@@ -91,6 +91,7 @@ LabEngine::LabEngine(OSystem *syst, const ADGameDescription *gameDesc)
_event = nullptr;
_resource = nullptr;
_music = nullptr;
+ _anim = nullptr;
_lastMessageLong = false;
_lastTooLong = false;
@@ -109,6 +110,7 @@ LabEngine::~LabEngine() {
delete _event;
delete _resource;
delete _music;
+ delete _anim;
}
Common::Error LabEngine::run() {
@@ -120,6 +122,7 @@ Common::Error LabEngine::run() {
_event = new EventManager(this);
_resource = new Resource(this);
_music = new Music(this);
+ _anim = new Anim(this);
if (getPlatform() == Common::kPlatformWindows) {
// Check if this is the Wyrmkeep trial
diff --git a/engines/lab/lab.h b/engines/lab/lab.h
index c427b08686..9327dbf562 100644
--- a/engines/lab/lab.h
+++ b/engines/lab/lab.h
@@ -40,6 +40,7 @@
#include "lab/mouse.h"
#include "lab/music.h"
#include "lab/resource.h"
+#include "lab/anim.h"
struct ADGameDescription;
@@ -103,6 +104,7 @@ public:
EventManager *_event;
Resource *_resource;
Music *_music;
+ Anim *_anim;
int _roomNum;
byte *_currentDisplayBuffer;
@@ -175,7 +177,6 @@ public:
void drawMap(uint16 CurRoom, uint16 CurMsg, uint16 Floor, bool fadeout, bool fadein);
void processMap(uint16 CurRoom);
void doMap(uint16 CurRoom);
- void diffNextFrame();
void drawJournal(uint16 wipenum, bool needFade);
void processJournal();
void doJournal();
diff --git a/engines/lab/labfun.h b/engines/lab/labfun.h
index 4f7573e0b1..c1a6b35a09 100644
--- a/engines/lab/labfun.h
+++ b/engines/lab/labfun.h
@@ -213,6 +213,10 @@ void mouseCombination(Common::Point pos);
void showTile(const char *filename, bool showsolution);
void mouseTile(Common::Point pos);
+void blackScreen();
+void blackAllScreen();
+void whiteScreen();
+
} // End of namespace Lab
#endif /* LAB_LABFUN_H */
diff --git a/engines/lab/map.cpp b/engines/lab/map.cpp
index 36b01d10f7..1f4f0dbfe1 100644
--- a/engines/lab/map.cpp
+++ b/engines/lab/map.cpp
@@ -30,7 +30,7 @@
#include "lab/lab.h"
#include "lab/labfun.h"
-#include "lab/diff.h"
+#include "lab/anim.h"
#include "lab/text.h"
#include "lab/mouse.h"
#include "lab/parsefun.h"
diff --git a/engines/lab/module.mk b/engines/lab/module.mk
index c9682f256a..4f1ace8c9c 100644
--- a/engines/lab/module.mk
+++ b/engines/lab/module.mk
@@ -2,6 +2,7 @@ MODULE := engines/lab
MODULE_OBJS := \
allocroom.o \
+ anim.o \
detection.o \
engine.o \
graphics.o \
@@ -21,7 +22,6 @@ MODULE_OBJS := \
special.o \
text.o \
timing.o \
- undiff.o \
vga.o
diff --git a/engines/lab/processroom.cpp b/engines/lab/processroom.cpp
index 04fe70d3fd..5807227c51 100644
--- a/engines/lab/processroom.cpp
+++ b/engines/lab/processroom.cpp
@@ -35,7 +35,7 @@
#include "lab/parsetypes.h"
#include "lab/parsefun.h"
#include "lab/resource.h"
-#include "lab/diff.h"
+#include "lab/anim.h"
#include "lab/interface.h"
namespace Lab {
@@ -49,8 +49,7 @@ InventoryData *Inventory;
uint16 NumInv, ManyRooms, HighestCondition, Direction;
const char *NewFileName;
-extern bool DoNotDrawMessage, IsBM, noupdatediff, QuitLab, MusicOn, DoBlack, LongWinInFront;
-extern char diffcmap[256 * 3];
+extern bool DoNotDrawMessage, noupdatediff, QuitLab, MusicOn, LongWinInFront;
extern const char *CurFileName;
extern CloseDataPtr CPtr;
@@ -379,7 +378,7 @@ static void doActions(Action * APtr, CloseDataPtr *LCPtr) {
case NOUPDATE:
noupdatediff = true;
- DoBlack = false;
+ g_lab->_anim->DoBlack = false;
break;
case FORCEUPDATE:
@@ -445,7 +444,7 @@ static void doActions(Action * APtr, CloseDataPtr *LCPtr) {
g_lab->_roomNum = APtr->Param1;
Direction = APtr->Param2 - 1;
*LCPtr = NULL;
- DoBlack = true;
+ g_lab->_anim->DoBlack = true;
break;
case SETCLOSEUP:
@@ -485,7 +484,7 @@ static void doActions(Action * APtr, CloseDataPtr *LCPtr) {
while (1) {
g_lab->_music->updateMusic();
- g_lab->diffNextFrame();
+ g_lab->_anim->diffNextFrame();
g_lab->getTime(&CurSecs, &CurMicros);
if ((CurSecs > StartSecs) || ((CurSecs == StartSecs) &&
@@ -520,7 +519,7 @@ static void doActions(Action * APtr, CloseDataPtr *LCPtr) {
case WAITSOUND:
while (g_lab->_music->isSoundEffectActive()) {
g_lab->_music->updateMusic();
- g_lab->diffNextFrame();
+ g_lab->_anim->diffNextFrame();
g_lab->waitTOF();
}
@@ -555,17 +554,17 @@ static void doActions(Action * APtr, CloseDataPtr *LCPtr) {
case SPECIALCMD:
if (APtr->Param1 == 0)
- DoBlack = true;
+ g_lab->_anim->DoBlack = true;
else if (APtr->Param1 == 1)
- DoBlack = (CPtr == NULL);
+ g_lab->_anim->DoBlack = (CPtr == NULL);
else if (APtr->Param1 == 2)
- DoBlack = (CPtr != NULL);
+ g_lab->_anim->DoBlack = (CPtr != NULL);
else if (APtr->Param1 == 5) { /* inverse the palette */
for (uint16 idx = (8 * 3); idx < (255 * 3); idx++)
- diffcmap[idx] = 255 - diffcmap[idx];
+ g_lab->_anim->diffcmap[idx] = 255 - g_lab->_anim->diffcmap[idx];
g_lab->waitTOF();
- g_lab->setPalette(diffcmap, 256);
+ g_lab->setPalette(g_lab->_anim->diffcmap, 256);
g_lab->waitTOF();
g_lab->waitTOF();
} else if (APtr->Param1 == 4) { /* white the palette */
@@ -574,7 +573,7 @@ static void doActions(Action * APtr, CloseDataPtr *LCPtr) {
g_lab->waitTOF();
} else if (APtr->Param1 == 6) { /* Restore the palette */
g_lab->waitTOF();
- g_lab->setPalette(diffcmap, 256);
+ g_lab->setPalette(g_lab->_anim->diffcmap, 256);
g_lab->waitTOF();
g_lab->waitTOF();
} else if (APtr->Param1 == 7) { /* Quick pause */
@@ -595,7 +594,7 @@ static void doActions(Action * APtr, CloseDataPtr *LCPtr) {
} else {
while (g_lab->_music->isSoundEffectActive()) {
g_lab->_music->updateMusic();
- g_lab->diffNextFrame();
+ g_lab->_anim->diffNextFrame();
g_lab->waitTOF();
}
}
diff --git a/engines/lab/readdiff.cpp b/engines/lab/readdiff.cpp
index abaa4f54fe..43309ffd78 100644
--- a/engines/lab/readdiff.cpp
+++ b/engines/lab/readdiff.cpp
@@ -29,400 +29,16 @@
*/
#include "lab/lab.h"
-#include "lab/diff.h"
+#include "lab/anim.h"
#include "lab/labfun.h"
#include "lab/mouse.h"
namespace Lab {
-
-static bool PlayOnce = false;
-static bool StopPlayingEnd = false;
-
-static uint32 header, size, WaitSec = 0L, WaitMicros = 0L, DelayMicros = 0L;
-static uint16 CurBit = 0, framenumber = 0, samplespeed, numchunks = 1;
-static byte *Buffer, temp[5];
-static bool donepal = false;
-static byte *storagefordifffile, **difffile = &storagefordifffile;
-static byte *start;
-static uint32 diffwidth, diffheight;
-static byte blackbuffer[256 * 3];
-
-bool DoBlack = false, /* Black the screen before new picture */
- nopalchange = false, /* Don't change the palette. */
- IsBM = false, /* Just fill in the RawDIFFBM structure */
- stopsound = false,
- waitForEffect = false; /* Wait for each sound effect to finish
- before coninuing. */
-
-static bool continuous,
- IsPlaying = false,
- IsAnim = false,
- IsPal = false;
+static byte temp[5];
uint16 _dataBytesPerRow;
-DIFFHeader headerdata;
-char diffcmap[256 * 3];
-BitMap RawDiffBM;
-
-extern BitMap *DispBitMap, *DrawBitMap;
-extern byte **startoffile;
-
-#define CONTINUOUS 0xFFFF
-
-
-/*****************************************************************************/
-/* Does the undiffing between the bitmaps. */
-/*****************************************************************************/
-void unDiff(byte *NewBuf, byte *OldBuf, byte *DiffData, uint16 bytesperrow, bool IsV) {
- byte buftype;
-
- DiffData++;
- buftype = *DiffData;
- DiffData++;
-
- if (IsV)
- VUnDIFFMemory(NewBuf, DiffData, 1, buftype + 1, bytesperrow);
- else
- unDIFFMemory(NewBuf, DiffData, 1, buftype + 1);
-}
-
-
-/*****************************************************************************/
-/* Changes the front screen to black. */
-/*****************************************************************************/
-void blackScreen() {
- memset(blackbuffer, 0, 248 * 3);
- g_lab->writeColorRegs(blackbuffer, 8, 248);
-
- g_system->delayMillis(32);
-}
-
-/*****************************************************************************/
-/* Changes the front screen to white. */
-/*****************************************************************************/
-void whiteScreen() {
- memset(blackbuffer, 255, 248 * 3);
- g_lab->writeColorRegs(blackbuffer, 8, 248);
-}
-
-/*****************************************************************************/
-/* Changes the entire screen to black. */
-/*****************************************************************************/
-void blackAllScreen() {
- memset(blackbuffer, 0, 256 * 3);
- g_lab->writeColorRegs(blackbuffer, 0, 256);
-
- g_system->delayMillis(32);
-}
-
-void LabEngine::diffNextFrame() {
- if (header == 65535) /* Already done. */
- return;
-
- if (DispBitMap->_flags & BITMAPF_VIDEO) {
- DispBitMap->_planes[0] = getCurrentDrawingBuffer();
- DispBitMap->_planes[1] = DispBitMap->_planes[0] + 0x10000;
- DispBitMap->_planes[2] = DispBitMap->_planes[1] + 0x10000;
- DispBitMap->_planes[3] = DispBitMap->_planes[2] + 0x10000;
- DispBitMap->_planes[4] = DispBitMap->_planes[3] + 0x10000;
- }
-
- _event->mouseHide();
-
- while (1) {
- if (CurBit >= numchunks) {
- _event->mouseShow();
-
- if (!IsBM) {
- if (headerdata._fps) {
- waitForTime(WaitSec, WaitMicros);
- addCurTime(0L, DelayMicros, &WaitSec, &WaitMicros);
- }
-
- if (IsPal && !nopalchange) {
- setPalette(diffcmap, 256);
- IsPal = false;
- }
-
- donepal = true;
- }
-
- if (IsPal && !nopalchange && !IsBM && !donepal) {
- setPalette(diffcmap, 256);
- IsPal = false;
- }
-
- donepal = false;
-
- framenumber++;
-
- if ((framenumber == 1) && (continuous || (!PlayOnce)))
- Buffer = *difffile;
-
- IsAnim = (framenumber >= 3) && (!PlayOnce);
- CurBit = 0;
-
- if (DispBitMap->_flags & BITMAPF_VIDEO)
- screenUpdate();
-
- return; /* done with the next frame. */
- }
-
- _music->updateMusic();
- header = READ_LE_UINT32(*difffile);
- *difffile += 4;
-
- size = READ_LE_UINT32(*difffile);
- *difffile += 4;
-
- switch (header) {
- case 8L:
- readBlock(diffcmap, size, difffile);
- IsPal = true;
- break;
-
- case 10L:
- RawDiffBM._planes[CurBit] = *difffile;
-
- if (IsBM)
- (*difffile) += size;
- else {
- readBlock(DrawBitMap->_planes[CurBit], size, difffile);
- }
-
- CurBit++;
- break;
-
- case 11L:
- (*difffile) += 4;
- runLengthDecode(DrawBitMap->_planes[CurBit], *difffile);
- CurBit++;
- (*difffile) += size - 4;
- break;
-
- case 12L:
- (*difffile) += 4;
- VRunLengthDecode(DrawBitMap->_planes[CurBit], *difffile, DrawBitMap->_bytesPerRow);
- CurBit++;
- (*difffile) += size - 4;
- break;
-
- case 20L:
- unDiff(DrawBitMap->_planes[CurBit], DispBitMap->_planes[CurBit], *difffile, DrawBitMap->_bytesPerRow, false);
- CurBit++;
- (*difffile) += size;
- break;
-
- case 21L:
- unDiff(DrawBitMap->_planes[CurBit], DispBitMap->_planes[CurBit], *difffile, DrawBitMap->_bytesPerRow, true);
- CurBit++;
- (*difffile) += size;
- break;
-
- case 25L:
- CurBit++;
- break;
-
- case 26L:
- CurBit++;
- break;
-
- case 30L:
- case 31L: {
- if (waitForEffect) {
- while (_music->isSoundEffectActive()) {
- _music->updateMusic();
- waitTOF();
- }
- }
-
- size -= 8L;
-
-
- (*difffile) += 4;
- samplespeed = READ_LE_UINT16(*difffile);
- (*difffile) += 4;
-
- byte *music = *difffile;
- uint32 musicsize = size;
- (*difffile) += size;
-
- _music->playSoundEffect(samplespeed, musicsize, music);
- break;
- }
- case 65535L:
- if ((framenumber == 1) || PlayOnce || StopPlayingEnd) {
- int didTOF = 0;
-
- if (waitForEffect) {
- while (_music->isSoundEffectActive()) {
- _music->updateMusic();
- waitTOF();
-
- if (DispBitMap->_flags & BITMAPF_VIDEO)
- didTOF = 1;
- }
- }
-
- IsPlaying = false;
- _event->mouseShow();
-
- if (!didTOF)
- screenUpdate();
-
- return;
- }
-
- framenumber = 4; /* Random frame number so it never gets back to 2 */
- *difffile = Buffer;
- break;
-
- default:
- (*difffile) += size;
- break;
- }
- }
-}
-
-/*****************************************************************************/
-/* A separate task launched by readDiff. Plays the DIFF. */
-/*****************************************************************************/
-void playDiff() {
- WaitSec = 0L;
- WaitMicros = 0L;
- DelayMicros = 0L;
- header = 0;
- CurBit = 0;
- framenumber = 0;
- numchunks = 1;
- donepal = false;
- StopPlayingEnd = false;
- difffile = &storagefordifffile;
-
- IsPlaying = true;
-
- if (DoBlack) {
- DoBlack = false;
- blackScreen();
- }
-
- start = *startoffile; /* Make a copy of the pointer to the start of the file */
- *difffile = start; /* Now can modify the file without modifying the original */
-
- if (start == NULL) {
- IsPlaying = false;
- return;
- }
-
- continuous = false;
- uint32 signature = READ_BE_UINT32(*difffile);
- (*difffile) += 4;
-
- header = READ_LE_UINT32(*difffile);
- (*difffile) += 4;
-
- if ((signature != MKTAG('D', 'I', 'F', 'F')) || (header != 1219009121L)) {
- IsPlaying = false;
- return;
- }
-
- header = READ_LE_UINT32(*difffile);
- (*difffile) += 4;
-
- size = READ_LE_UINT32(*difffile);
- (*difffile) += 4;
-
- if (header == 0) {
- // sizeof(headerdata) != 18, but the padding might be at the end
- headerdata._version = READ_LE_UINT16(*difffile);
- (*difffile) += 2;
- headerdata._width = READ_LE_UINT16(*difffile);
- (*difffile) += 2;
- headerdata._height = READ_LE_UINT16(*difffile);
- (*difffile) += 2;
- headerdata._depth = *difffile[0];
- (*difffile)++;
- headerdata._fps = *difffile[0];
- (*difffile)++;
- headerdata._bufferSize = READ_LE_UINT32(*difffile);
- (*difffile) += 4;
- headerdata._machine = READ_LE_UINT16(*difffile);
- (*difffile) += 2;
- headerdata._flags = READ_LE_UINT32(*difffile);
- (*difffile) += 4;
-
- (*difffile) += size - 18;
-
- continuous = CONTINUOUS & headerdata._flags;
- diffwidth = headerdata._width;
- diffheight = headerdata._height;
- _dataBytesPerRow = diffwidth;
-
- numchunks = (((int32) diffwidth) * diffheight) / 0x10000;
-
- if ((uint32)(numchunks * 0x10000) < (uint32)(((int32) diffwidth) * diffheight))
- numchunks++;
- } else {
- return;
- }
-
- for (header = 0; header < 8; header++)
- RawDiffBM._planes[header] = NULL;
-
- if (headerdata._fps)
- DelayMicros = ONESECOND / headerdata._fps;
-
- if (PlayOnce) {
- while (header != 65535)
- g_lab->diffNextFrame();
- } else
- g_lab->diffNextFrame();
-}
-
-
-
-/*****************************************************************************/
-/* Stops an animation from running. */
-/*****************************************************************************/
-void stopDiff() {
- if (IsPlaying) {
- if (IsAnim)
- blackScreen();
- }
-}
-
-/*****************************************************************************/
-/* Stops an animation from running. */
-/*****************************************************************************/
-void stopDiffEnd() {
- if (IsPlaying) {
- StopPlayingEnd = true;
- while (IsPlaying) {
- g_lab->_music->updateMusic();
- g_lab->diffNextFrame();
- }
- }
-}
-
-
-/*****************************************************************************/
-/* Stops the continuous sound from playing. */
-/*****************************************************************************/
-void stopSound() {
- stopsound = true;
-}
-
-/*****************************************************************************/
-/* Reads in a DIFF file. */
-/*****************************************************************************/
-bool readDiff(bool playonce) {
- PlayOnce = playonce;
- playDiff();
- return true;
-}
-
-void readSound(bool waitTillFinished, Common::File *file) {
+void Anim::readSound(bool waitTillFinished, Common::File *file) {
uint32 magicBytes = file->readUint32LE();
if (magicBytes != 1219009121L)
return;
diff --git a/engines/lab/special.cpp b/engines/lab/special.cpp
index e23ea7035b..afe3efb64f 100644
--- a/engines/lab/special.cpp
+++ b/engines/lab/special.cpp
@@ -37,7 +37,7 @@
#include "lab/labfun.h"
#include "lab/parsefun.h"
#include "lab/interface.h"
-#include "lab/diff.h"
+#include "lab/anim.h"
#include "lab/text.h"
#include "lab/mouse.h"
#include "lab/parsetypes.h"
@@ -83,9 +83,7 @@ uint16 CurTile[4][4] = {
extern TextFont *MsgFont;
extern uint16 *FadePalette;
-extern bool nopalchange, DoBlack;
extern BitMap *DispBitMap, *DrawBitMap;
-extern char diffcmap[3 * 256];
extern CloseDataPtr CPtr;
extern InventoryData *Inventory;
extern uint16 Direction;
@@ -111,7 +109,7 @@ static byte *loadBackPict(const char *fileName, bool tomem) {
byte *res = NULL;
FadePalette = hipal;
- nopalchange = true;
+ g_lab->_anim->nopalchange = true;
if (tomem)
res = readPictToMem(fileName, g_lab->_screenWidth, g_lab->_screenHeight);
@@ -119,12 +117,12 @@ static byte *loadBackPict(const char *fileName, bool tomem) {
readPict(fileName, true);
for (uint16 i = 0; i < 16; i++) {
- hipal[i] = ((diffcmap[i * 3] >> 2) << 8) +
- ((diffcmap[i * 3 + 1] >> 2) << 4) +
- ((diffcmap[i * 3 + 2] >> 2));
+ hipal[i] = ((g_lab->_anim->diffcmap[i * 3] >> 2) << 8) +
+ ((g_lab->_anim->diffcmap[i * 3 + 1] >> 2) << 4) +
+ ((g_lab->_anim->diffcmap[i * 3 + 2] >> 2));
}
- nopalchange = false;
+ g_lab->_anim->nopalchange = false;
return res;
}
@@ -144,10 +142,10 @@ void showCombination(const char *filename) {
byte **buffer;
resetBuffer();
- DoBlack = true;
- nopalchange = true;
+ g_lab->_anim->DoBlack = true;
+ g_lab->_anim->nopalchange = true;
readPict(filename, true);
- nopalchange = false;
+ g_lab->_anim->nopalchange = false;
blackScreen();
@@ -160,7 +158,7 @@ void showCombination(const char *filename) {
doCombination();
- g_lab->setPalette(diffcmap, 256);
+ g_lab->setPalette(g_lab->_anim->diffcmap, 256);
}
@@ -287,10 +285,10 @@ void showTile(const char *filename, bool showsolution) {
byte **buffer;
resetBuffer();
- DoBlack = true;
- nopalchange = true;
+ g_lab->_anim->DoBlack = true;
+ g_lab->_anim->nopalchange = true;
readPict(filename, true);
- nopalchange = false;
+ g_lab->_anim->nopalchange = false;
blackScreen();
if (showsolution) {
@@ -311,7 +309,7 @@ void showTile(const char *filename, bool showsolution) {
doTile(showsolution);
- g_lab->setPalette(diffcmap, 256);
+ g_lab->setPalette(g_lab->_anim->diffcmap, 256);
}
static void scrollRaster(int16 dx, int16 dy, uint16 x1, uint16 y1, uint16 x2, uint16 y2) {
@@ -425,7 +423,7 @@ static void changeTile(uint16 col, uint16 row) {
if (check) {
g_lab->_conditions->inclElement(BRICKOPEN); /* unlocked combination */
- DoBlack = true;
+ g_lab->_anim->DoBlack = true;
check = readPict("p:Up/BDOpen", true);
}
}
@@ -458,7 +456,7 @@ void doNotes() {
char *ntext = g_lab->_resource->getText("Lab:Rooms/Notes");
flowText(noteFont, -2 + SVGACord(1), 0, 0, false, false, true, true, VGAScaleX(25) + SVGACord(15), VGAScaleY(50), VGAScaleX(295) - SVGACord(15), VGAScaleY(148), ntext);
- g_lab->setPalette(diffcmap, 256);
+ g_lab->setPalette(g_lab->_anim->diffcmap, 256);
closeFont(noteFont);
delete[] ntext;
@@ -502,7 +500,7 @@ void doWestPaper() {
delete[] ntext;
closeFont(paperFont);
- g_lab->setPalette(diffcmap, 256);
+ g_lab->setPalette(g_lab->_anim->diffcmap, 256);
freeAllStolenMem();
}
@@ -674,14 +672,14 @@ void LabEngine::drawJournal(uint16 wipenum, bool needFade) {
if (needFade)
fade(true, 0);
- nopalchange = true;
+ g_lab->_anim->nopalchange = true;
JBackImage.ImageData = readPictToMem("P:Journal.pic", _screenWidth, _screenHeight);
GotBackImage = true;
eatMessages();
_event->mouseShow();
- nopalchange = false;
+ g_lab->_anim->nopalchange = false;
}
/*****************************************************************************/
diff --git a/engines/lab/undiff.cpp b/engines/lab/undiff.cpp
deleted file mode 100644
index e5f193c777..0000000000
--- a/engines/lab/undiff.cpp
+++ /dev/null
@@ -1,379 +0,0 @@
-/* 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/endian.h"
-#include "lab/lab.h"
-
-namespace Lab {
-
-extern uint16 _dataBytesPerRow;
-
-/*------------------------ unDiff Horizontal Memory -------------------------*/
-
-/*****************************************************************************/
-/* Undiffs a piece of memory when header size is a byte, and copy/skip size */
-/* is also a byte. */
-/*****************************************************************************/
-static void 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. */
-/*****************************************************************************/
-static void 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--;
- }
- }
-}
-
-
-
-/*****************************************************************************/
-/* UnDiffs a coded DIFF string onto an already initialized piece of memory. */
-/*****************************************************************************/
-bool unDIFFMemory(byte *dest, byte *diff, uint16 headerSize, uint16 copySize) {
- if (headerSize == 1) {
- if (copySize == 1)
- unDIFFByteByte(dest, diff);
-
- else if (copySize == 2)
- unDIFFByteWord((uint16 *)dest, (uint16 *)diff);
-
- else
- return false;
- } else
- error("unDIFFMemory: HeaderSize is %d", headerSize);
-
- return true;
-}
-
-/*------------------------- unDiff Vertical Memory --------------------------*/
-
-/*****************************************************************************/
-/* Undiffs a piece of memory when header size is a byte, and copy/skip size */
-/* is a byte. */
-/*****************************************************************************/
-static void 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. */
-/*****************************************************************************/
-static void VUnDIFFByteWord(uint16 *Dest, uint16 *diff, uint16 bytesperrow) {
- uint16 *CurPtr;
- uint16 skip, copy;
- uint16 counter = 0, wordsperrow;
-
-
- 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. */
-/*****************************************************************************/
-static void VUnDIFFByteLong(uint32 *Dest, uint32 *diff, uint16 bytesperrow) {
- uint32 *CurPtr;
- uint16 skip, copy;
- uint16 counter = 0, longsperrow;
- byte *diff1 = (byte *)diff;
-
-
- 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--;
- }
- }
- }
- }
-}
-
-
-
-
-/*****************************************************************************/
-/* UnDiffs a coded DIFF string onto an already initialized piece of memory. */
-/*****************************************************************************/
-bool VUnDIFFMemory(byte *Dest, byte *diff, uint16 HeaderSize, uint16 CopySize, uint16 bytesperrow) {
- if (HeaderSize == 1) {
- if (CopySize == 1)
- VUnDIFFByteByte(Dest, diff, bytesperrow);
-
- else if (CopySize == 2)
- VUnDIFFByteWord((uint16 *)Dest, (uint16 *)diff, bytesperrow);
-
- else if (CopySize == 4)
- VUnDIFFByteLong((uint32 *)Dest, (uint32 *)diff, bytesperrow);
-
- else
- return false;
- } else
- return (false);
-
- return true;
-}
-
-
-/*****************************************************************************/
-/* Runlength decodes a chunk of memory. */
-/*****************************************************************************/
-void 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 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++;
- }
- }
-}
-
-} // End of namespace Lab