LAB: Introduce the Anim class (WIP)

This commit is contained in:
Strangerke 2015-12-01 20:10:42 +01:00 committed by Willem Jan Palenstijn
parent 83d88cab80
commit d656aa4859
14 changed files with 928 additions and 904 deletions

728
engines/lab/anim.cpp Normal file
View file

@ -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

View file

@ -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 */
class Anim {
private:
LabEngine *_vm;
void initOffsets(uint16 bytesPerRow);
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;
bool unDIFFMemory(byte *dest, /* Where to Un-DIFF */
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);
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();
/* 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();
};
} // End of namespace Lab

View file

@ -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();
}
}

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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();

View file

@ -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 */

View file

@ -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"

View file

@ -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

View file

@ -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();
}
}

View file

@ -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;

View file

@ -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;
}
/*****************************************************************************/

View file

@ -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