diff options
author | Strangerke | 2015-12-01 20:10:42 +0100 |
---|---|---|
committer | Willem Jan Palenstijn | 2015-12-23 21:33:46 +0100 |
commit | d656aa4859352e3d08e15346a482c943c1868502 (patch) | |
tree | 8810990fe5b132184c4224f7b702f8b0cfd73c43 /engines/lab | |
parent | 83d88cab8065613c71f91ce2b941b00192694ae1 (diff) | |
download | scummvm-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.cpp | 728 | ||||
-rw-r--r-- | engines/lab/anim.h (renamed from engines/lab/diff.h) | 75 | ||||
-rw-r--r-- | engines/lab/engine.cpp | 66 | ||||
-rw-r--r-- | engines/lab/graphics.cpp | 75 | ||||
-rw-r--r-- | engines/lab/intro.cpp | 40 | ||||
-rw-r--r-- | engines/lab/lab.cpp | 7 | ||||
-rw-r--r-- | engines/lab/lab.h | 3 | ||||
-rw-r--r-- | engines/lab/labfun.h | 4 | ||||
-rw-r--r-- | engines/lab/map.cpp | 2 | ||||
-rw-r--r-- | engines/lab/module.mk | 2 | ||||
-rw-r--r-- | engines/lab/processroom.cpp | 27 | ||||
-rw-r--r-- | engines/lab/readdiff.cpp | 390 | ||||
-rw-r--r-- | engines/lab/special.cpp | 40 | ||||
-rw-r--r-- | engines/lab/undiff.cpp | 379 |
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, µs); g_lab->anyTimeDiff(lastsecs, lastmicros, secs, micros, &secs, µs); @@ -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 |