LAB: Introduce the Anim class (WIP)
This commit is contained in:
parent
83d88cab80
commit
d656aa4859
14 changed files with 928 additions and 904 deletions
728
engines/lab/anim.cpp
Normal file
728
engines/lab/anim.cpp
Normal 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
|
|
@ -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
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue