aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorSven Hesse2007-03-29 17:55:39 +0000
committerSven Hesse2007-03-29 17:55:39 +0000
commit623ca8802269914ab90a1127f89c66dd2cb571f1 (patch)
tree184d67b016a4a3808d7b8a19946c071db39105ac /engines
parent69639ea0bf28e3ca7526617304859d359b58063b (diff)
downloadscummvm-rg350-623ca8802269914ab90a1127f89c66dd2cb571f1.tar.gz
scummvm-rg350-623ca8802269914ab90a1127f89c66dd2cb571f1.tar.bz2
scummvm-rg350-623ca8802269914ab90a1127f89c66dd2cb571f1.zip
- Properly implemented the ImdPlayer
- Some more clean-up svn-id: r26316
Diffstat (limited to 'engines')
-rw-r--r--engines/gob/cdrom.cpp16
-rw-r--r--engines/gob/dataio.cpp58
-rw-r--r--engines/gob/dataio.h12
-rw-r--r--engines/gob/draw.cpp25
-rw-r--r--engines/gob/draw.h1
-rw-r--r--engines/gob/draw_v1.cpp4
-rw-r--r--engines/gob/draw_v2.cpp4
-rw-r--r--engines/gob/game.cpp22
-rw-r--r--engines/gob/game_v2.cpp2
-rw-r--r--engines/gob/global.h4
-rw-r--r--engines/gob/gob.cpp5
-rw-r--r--engines/gob/gob.h17
-rw-r--r--engines/gob/imd.cpp1342
-rw-r--r--engines/gob/imd.h58
-rw-r--r--engines/gob/init.cpp23
-rw-r--r--engines/gob/inter_v1.cpp14
-rw-r--r--engines/gob/inter_v2.cpp38
-rw-r--r--engines/gob/mult.cpp2
-rw-r--r--engines/gob/palanim.cpp8
-rw-r--r--engines/gob/parse.h4
-rw-r--r--engines/gob/sound.cpp17
-rw-r--r--engines/gob/sound.h7
-rw-r--r--engines/gob/util.cpp6
-rw-r--r--engines/gob/video.cpp29
-rw-r--r--engines/gob/video.h2
25 files changed, 1065 insertions, 655 deletions
diff --git a/engines/gob/cdrom.cpp b/engines/gob/cdrom.cpp
index a5c9fab90c..92cd167a52 100644
--- a/engines/gob/cdrom.cpp
+++ b/engines/gob/cdrom.cpp
@@ -66,14 +66,9 @@ void CDROM::readLIC(const char *fname) {
handle = _vm->_dataIO->openData(tmp);
- _vm->_dataIO->readData(handle, (char *)&version, 2);
- version = READ_LE_UINT16(&version);
-
- _vm->_dataIO->readData(handle, (char *)&startChunk, 2);
- startChunk = READ_LE_UINT16(&startChunk);
-
- _vm->_dataIO->readData(handle, (char *)&_numTracks, 2);
- _numTracks = READ_LE_UINT16(&_numTracks);
+ version = _vm->_dataIO->readUint16(handle);
+ startChunk = _vm->_dataIO->readUint16(handle);
+ _numTracks = _vm->_dataIO->readUint16(handle);
if (version != 3)
error("%s: Unknown version %d", fname, version);
@@ -81,8 +76,7 @@ void CDROM::readLIC(const char *fname) {
_vm->_dataIO->seekData(handle, 50, SEEK_SET);
for (int i = 0; i < startChunk; i++) {
- _vm->_dataIO->readData(handle, (char *)&pos, 2);
- pos = READ_LE_UINT16(&pos);
+ pos = _vm->_dataIO->readUint16(handle);
if (!pos)
break;
@@ -91,7 +85,7 @@ void CDROM::readLIC(const char *fname) {
}
_LICbuffer = new byte[_numTracks * 22];
- _vm->_dataIO->readData(handle, (char *)_LICbuffer, _numTracks * 22);
+ _vm->_dataIO->readData(handle, (char *) _LICbuffer, _numTracks * 22);
_vm->_dataIO->closeData(handle);
}
diff --git a/engines/gob/dataio.cpp b/engines/gob/dataio.cpp
index 7cb3b5c558..b1202a9250 100644
--- a/engines/gob/dataio.cpp
+++ b/engines/gob/dataio.cpp
@@ -39,6 +39,14 @@ DataIO::DataIO(GobEngine *vm) : _vm(vm) {
_packedSize = 0;
}
+DataIO::~DataIO() {
+ for (int i = 0; i < MAX_DATA_FILES; i++) {
+ if (_dataFiles[i])
+ file_getHandle(_dataFileHandles[i])->close();
+ delete[] _dataFiles[i];
+ }
+}
+
int32 DataIO::unpackData(char *sourceBuf, char *destBuf) {
uint32 realSize;
uint32 counter;
@@ -104,7 +112,7 @@ int32 DataIO::unpackData(char *sourceBuf, char *destBuf) {
}
Common::File *DataIO::file_getHandle(int16 handle) {
- return &_vm->_global->_filesHandles[handle];
+ return &_filesHandles[handle];
}
int16 DataIO::file_open(const char *path, Common::File::AccessMode mode) {
@@ -156,7 +164,7 @@ int16 DataIO::getChunk(const char *chunkName) {
}
char DataIO::freeChunk(int16 handle) {
- if ((handle >= 50) && (handle < 100)) {
+ if ((handle >= 50) && (handle < 128)) {
handle -= 50;
_chunkPos[(handle / 10) * MAX_SLOT_COUNT + (handle % 10)] = -1;
return 0;
@@ -170,7 +178,7 @@ int32 DataIO::readChunk(int16 handle, char *buf, uint16 size) {
int16 i;
int32 offset;
- if ((handle < 50) || (handle >= 100))
+ if ((handle < 50) || (handle >= 128))
return -2;
file = (handle - 50) / 10;
@@ -204,7 +212,7 @@ int16 DataIO::seekChunk(int16 handle, int32 pos, int16 from) {
int16 file;
int16 slot;
- if ((handle < 50) || (handle >= 100))
+ if ((handle < 50) || (handle >= 128))
return -1;
file = (handle - 50) / 10;
@@ -218,6 +226,19 @@ int16 DataIO::seekChunk(int16 handle, int32 pos, int16 from) {
return _chunkPos[file * MAX_SLOT_COUNT + slot];
}
+uint32 DataIO::getChunkPos(int16 handle) {
+ int16 file;
+ int16 slot;
+
+ if ((handle < 50) || (handle >= 128))
+ return 0xFFFFFFFF;
+
+ file = (handle - 50) / 10;
+ slot = (handle - 50) % 10;
+
+ return _chunkPos[file * MAX_SLOT_COUNT + slot];
+}
+
int32 DataIO::getChunkSize(const char *chunkName) {
int16 file;
int16 chunk;
@@ -370,6 +391,27 @@ int32 DataIO::readData(int16 handle, char *buf, uint16 size) {
return file_getHandle(handle)->read(buf, size);
}
+byte DataIO::readByte(int16 handle) {
+ char buf;
+
+ readData(handle, &buf, 1);
+ return ((byte) buf);
+}
+
+uint16 DataIO::readUint16(int16 handle) {
+ char buf[2];
+
+ readData(handle, buf, 2);
+ return READ_LE_UINT16(buf);
+}
+
+uint32 DataIO::readUint32(int16 handle) {
+ char buf[4];
+
+ readData(handle, buf, 4);
+ return READ_LE_UINT32(buf);
+}
+
int32 DataIO::writeData(int16 handle, char *buf, uint16 size) {
return file_getHandle(handle)->write(buf, size);
}
@@ -384,7 +426,13 @@ void DataIO::seekData(int16 handle, int32 pos, int16 from) {
file_getHandle(handle)->seek(pos, from);
}
-int32 DataIO::getPos(int16 handle) {
+uint32 DataIO::getPos(int16 handle) {
+ uint32 resPos;
+
+ resPos = getChunkPos(handle);
+ if (resPos != 0xFFFFFFFF)
+ return resPos;
+
return file_getHandle(handle)->pos();
}
diff --git a/engines/gob/dataio.h b/engines/gob/dataio.h
index 2fb90f15d5..9c29fea195 100644
--- a/engines/gob/dataio.h
+++ b/engines/gob/dataio.h
@@ -24,10 +24,14 @@
#ifndef GOB_DATAIO_H
#define GOB_DATAIO_H
+#include "common/stdafx.h"
+#include "common/endian.h"
+
#include "common/file.h"
namespace Gob {
+#define MAX_FILES 30
#define MAX_DATA_FILES 8
#define MAX_SLOT_COUNT 4
@@ -50,15 +54,20 @@ public:
int16 openData(const char *path,
Common::File::AccessMode mode = Common::File::kFileReadMode);
int32 readData(int16 handle, char *buf, uint16 size);
+ byte readByte(int16 handle);
+ uint16 readUint16(int16 handle);
+ uint32 readUint32(int16 handle);
int32 writeData(int16 handle, char *buf, uint16 size);
void seekData(int16 handle, int32 pos, int16 from);
- int32 getPos(int16 handle);
+ uint32 getPos(int16 handle);
int32 getDataSize(const char *name);
char *getData(const char *path);
DataIO(class GobEngine *vm);
+ ~DataIO();
protected:
+ Common::File _filesHandles[MAX_FILES];
struct ChunkDesc *_dataFiles[MAX_DATA_FILES];
int16 _numDataChunks[MAX_DATA_FILES];
int16 _dataFileHandles[MAX_DATA_FILES];
@@ -79,6 +88,7 @@ protected:
char freeChunk(int16 handle);
int32 readChunk(int16 handle, char *buf, uint16 size);
int16 seekChunk(int16 handle, int32 pos, int16 from);
+ uint32 getChunkPos(int16 handle);
int32 getChunkSize(const char *chunkName);
};
diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp
index 759b15bc37..eef044699c 100644
--- a/engines/gob/draw.cpp
+++ b/engines/gob/draw.cpp
@@ -246,10 +246,7 @@ void Draw::blitInvalidated() {
_showCursor = (_showCursor & ~2) | ((_showCursor & 1) << 1);
if (_applyPal) {
clearPalette();
-
- _vm->_video->drawSprite(_backSurface, _frontSurface,
- 0, 0, _vm->_video->_surfWidth - 1,
- _vm->_video->_surfHeight - 1, 0, 0, 0);
+ forceBlit();
setPalette();
_invalidatedCount = 0;
_noInvalidated = true;
@@ -390,4 +387,24 @@ int32 Draw::getSpriteRectSize(int16 index) {
return _spritesArray[index]->getWidth() * _spritesArray[index]->getHeight();
}
+void Draw::forceBlit(bool backwards) {
+ if ((_frontSurface == 0) || (_backSurface == 0))
+ return;
+ if (_frontSurface == _backSurface)
+ return;
+ if (_spritesArray[20] != _frontSurface)
+ return;
+ if (_spritesArray[21] != _backSurface)
+ return;
+
+ if (backwards)
+ _vm->_video->drawSprite(_frontSurface, _backSurface, 0, 0,
+ _frontSurface->getWidth() - 1, _frontSurface->getHeight() - 1,
+ 0, 0, 0);
+ else
+ _vm->_video->drawSprite(_backSurface, _frontSurface, 0, 0,
+ _backSurface->getWidth() - 1, _backSurface->getHeight() - 1,
+ 0, 0, 0);
+}
+
} // End of namespace Gob
diff --git a/engines/gob/draw.h b/engines/gob/draw.h
index 82b074fbee..8e973a8ee5 100644
--- a/engines/gob/draw.h
+++ b/engines/gob/draw.h
@@ -144,6 +144,7 @@ public:
void printTextCentered(int16 id, int16 left, int16 top, int16 right,
int16 bottom, char *str, int16 fontIndex, int16 color);
int32 getSpriteRectSize(int16 index);
+ void forceBlit(bool backwards = false);
virtual void initScreen() = 0;
virtual void closeScreen() = 0;
diff --git a/engines/gob/draw_v1.cpp b/engines/gob/draw_v1.cpp
index 27880e1f5f..74feea39aa 100644
--- a/engines/gob/draw_v1.cpp
+++ b/engines/gob/draw_v1.cpp
@@ -99,7 +99,7 @@ void Draw_v1::animateCursor(int16 cursor) {
} else {
if (_noInvalidated && (_vm->_global->_inter_mouseX == _cursorX) &&
(_vm->_global->_inter_mouseY == _cursorY)) {
- _vm->_video->waitRetrace(_vm->_global->_videoMode);
+ _vm->_video->waitRetrace();
return;
}
}
@@ -144,7 +144,7 @@ void Draw_v1::animateCursor(int16 cursor) {
blitInvalidated();
_cursorIndex = tmp;
} else {
- _vm->_video->waitRetrace(_vm->_global->_videoMode);
+ _vm->_video->waitRetrace();
if (MIN(newY, _cursorY) < 50)
_vm->_util->delay(5);
_showCursor = 0;
diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp
index 93cfe04be9..5aa6cbbbf1 100644
--- a/engines/gob/draw_v2.cpp
+++ b/engines/gob/draw_v2.cpp
@@ -126,7 +126,7 @@ void Draw_v2::animateCursor(int16 cursor) {
} else {
if (_noInvalidated && (_vm->_global->_inter_mouseX == _cursorX) &&
(_vm->_global->_inter_mouseY == _cursorY)) {
- _vm->_video->waitRetrace(_vm->_global->_videoMode);
+ _vm->_video->waitRetrace();
return;
}
}
@@ -170,7 +170,7 @@ void Draw_v2::animateCursor(int16 cursor) {
_cursorIndex = tmp;
} else {
_showCursor = 3;
- _vm->_video->waitRetrace(_vm->_global->_videoMode);
+ _vm->_video->waitRetrace();
if (MIN(newY, _cursorY) < 50)
_vm->_util->delay(5);
}
diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp
index 221ee46d30..9ed83ecf18 100644
--- a/engines/gob/game.cpp
+++ b/engines/gob/game.cpp
@@ -352,28 +352,22 @@ void Game::loadExtTable(void) {
if (_extHandle < 0)
return;
- _vm->_dataIO->readData(_extHandle, (char *) &count, 2);
- count = FROM_LE_16(count);
+ count = _vm->_dataIO->readUint16(_extHandle);
- _vm->_dataIO->seekData(_extHandle, 0, 0);
+ _vm->_dataIO->seekData(_extHandle, 0, SEEK_SET);
_extTable = new ExtTable;
_extTable->items = 0;
if (count)
_extTable->items = new ExtItem[count];
- _vm->_dataIO->readData(_extHandle, (char *) &_extTable->itemsCount, 2);
- _extTable->itemsCount = FROM_LE_16(_extTable->itemsCount);
- _vm->_dataIO->readData(_extHandle, (char *) &_extTable->unknown, 1);
+ _extTable->itemsCount = _vm->_dataIO->readUint16(_extHandle);
+ _extTable->unknown = _vm->_dataIO->readByte(_extHandle);
for (int i = 0; i < count; i++) {
- _vm->_dataIO->readData(_extHandle, (char *) &_extTable->items[i].offset, 4);
- _extTable->items[i].offset = FROM_LE_32(_extTable->items[i].offset);
- _vm->_dataIO->readData(_extHandle, (char *) &_extTable->items[i].size, 2);
- _extTable->items[i].size = FROM_LE_16(_extTable->items[i].size);
- _vm->_dataIO->readData(_extHandle, (char *) &_extTable->items[i].width, 2);
- _extTable->items[i].width = FROM_LE_16(_extTable->items[i].width);
- _vm->_dataIO->readData(_extHandle, (char *) &_extTable->items[i].height, 2);
- _extTable->items[i].height = FROM_LE_16(_extTable->items[i].height);
+ _extTable->items[i].offset = _vm->_dataIO->readUint32(_extHandle);
+ _extTable->items[i].size = _vm->_dataIO->readUint16(_extHandle);
+ _extTable->items[i].width = _vm->_dataIO->readUint16(_extHandle);
+ _extTable->items[i].height = _vm->_dataIO->readUint16(_extHandle);
}
}
diff --git a/engines/gob/game_v2.cpp b/engines/gob/game_v2.cpp
index bcd3da4d2f..e9d10fe8b1 100644
--- a/engines/gob/game_v2.cpp
+++ b/engines/gob/game_v2.cpp
@@ -439,7 +439,7 @@ int16 Game_v2::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId,
_vm->_draw->animateCursor(-1);
else
_vm->_draw->blitInvalidated();
- _vm->_video->waitRetrace(_vm->_global->_videoMode);
+ _vm->_video->waitRetrace();
}
key = checkKeys(&_vm->_global->_inter_mouseX,
diff --git a/engines/gob/global.h b/engines/gob/global.h
index fb455a426c..14e1adcbfc 100644
--- a/engines/gob/global.h
+++ b/engines/gob/global.h
@@ -55,8 +55,6 @@ namespace Gob {
#define ESCAPE 0x001B
#define ENTER 0x000D
-#define MAX_FILES 30
-
/* Video drivers */
#define UNK_DRIVER 0
#define VGA_DRIVER 1
@@ -94,8 +92,6 @@ public:
char _useJoystick;
- Common::File _filesHandles[MAX_FILES];
-
int16 _primaryWidth;
int16 _primaryHeight;
diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp
index 81d61e3734..ae0bbf0722 100644
--- a/engines/gob/gob.cpp
+++ b/engines/gob/gob.cpp
@@ -410,9 +410,8 @@ void GobEngine::loadGameData(enum SaveFiles sFile, int16 dataVar, int32 size, in
_vm->_video->drawSprite(_global->_savedBack, destDesc, 0, 0,
destDesc->getWidth() - 1, destDesc->getHeight() - 1, 0, 0, 0);
if (index == 21) {
- _video->drawSprite(_draw->_backSurface, _draw->_frontSurface, 0, 0,
- _draw->_frontSurface->getWidth() - 1, _draw->_frontSurface->getHeight() - 1, 0, 0, 0);
- _video->waitRetrace(_global->_videoMode);
+ _vm->_draw->forceBlit();
+ _video->waitRetrace();
}
WRITE_VAR(1, 0);
diff --git a/engines/gob/gob.h b/engines/gob/gob.h
index 6f64053fe6..a3da4f4fd3 100644
--- a/engines/gob/gob.h
+++ b/engines/gob/gob.h
@@ -109,11 +109,14 @@ class ReferenceCounter {
public:
class Ptr {
public:
- T* operator-> () { return _p; }
- T& operator* () { return *_p; }
+ bool operator==(const Ptr &p) const { return _p == p._p; }
+ bool operator==(const ReferenceCounter *p) const { return _p == p; }
+
+ T *operator-> () { return _p; }
+ T &operator* () { return *_p; }
operator T*() { return _p; }
- Ptr(T* p) : _p(p) { ++_p->_references; }
+ Ptr(T *p) : _p(p) { ++_p->_references; }
Ptr() : _p(0) { }
~Ptr() {
@@ -121,16 +124,16 @@ public:
delete _p;
}
- Ptr(const Ptr& p) : _p(p._p) { ++_p->_references; }
+ Ptr(const Ptr &p) : _p(p._p) { ++_p->_references; }
- Ptr& operator= (const Ptr& p) {
+ Ptr &operator= (const Ptr &p) {
++p._p->_references;
if (_p && (--_p->_references == 0))
delete _p;
_p = p._p;
return *this;
}
- Ptr* operator= (const Ptr* p) {
+ Ptr *operator= (const Ptr *p) {
if (p)
++p->_p->_references;
if (_p && (--_p->_references == 0))
@@ -141,7 +144,7 @@ public:
}
private:
- T* _p;
+ T *_p;
};
ReferenceCounter() : _references(0) { }
diff --git a/engines/gob/imd.cpp b/engines/gob/imd.cpp
index 48789ea39a..7f2ad3d211 100644
--- a/engines/gob/imd.cpp
+++ b/engines/gob/imd.cpp
@@ -44,9 +44,11 @@ ImdPlayer::ImdPlayer(GobEngine *vm) : _vm(vm) {
_curX = 0;
_curY = 0;
+ _left = 0;
+ _top = 0;
+ _right = 0;
+ _bottom = 0;
- _frameDataSize = 0;
- _vidBufferSize = 0;
_frameData = 0;
_vidBuffer = 0;
@@ -54,35 +56,42 @@ ImdPlayer::ImdPlayer(GobEngine *vm) : _vm(vm) {
_backSurf = 21;
_frontMem = 0;
_frameDelay = 0;
+
+ _noSound = true;
+ _soundBuffer = 0;
+
+ _soundFreq = 0;
+ _soundSliceSize = 0;
+ _soundSlicesCount = 0;
+
+ _soundSliceLength = 0;
+ _curSoundSlice = 0;
+ _soundStage = 0;
}
ImdPlayer::~ImdPlayer() {
if (_curImd) {
- _curImd->surfDesc = 0;
delete[] _curImd->palette;
delete[] _curImd->framesPos;
delete[] _curImd->frameCoords;
+ delete[] _curImd->extraPalette;
}
delete[] _frameData;
delete[] _vidBuffer;
delete[] _frontMem;
+ delete[] _soundBuffer;
delete _curImd;
}
-// flagsBit: 0 = read and set palette
-// 1 = read palette
+// flag bits: 0 = read and set palette
+// 1 = read palette
ImdPlayer::Imd *ImdPlayer::loadImdFile(const char *path, SurfaceDesc *surfDesc, int8 flags) {
- int i;
Imd *imdPtr;
int16 handle;
- bool setAllPalBak;
char buf[18];
- Video::Color *palBak;
+ uint32 framesPosPos = 0;
+ uint32 framesCordsPos = 0;
- int32 byte_31449 = 0;
- int32 byte_3144D = 0;
-
- buf[0] = 0;
strcpy(buf, path);
strcat(buf, ".IMD");
@@ -94,226 +103,204 @@ ImdPlayer::Imd *ImdPlayer::loadImdFile(const char *path, SurfaceDesc *surfDesc,
}
imdPtr = new Imd;
+ assert(imdPtr);
memset(imdPtr, 0, sizeof(Imd));
- _vm->_dataIO->readData(handle, buf, 18);
-
- // "fileHandle" holds the major version while loading
- imdPtr->fileHandle = READ_LE_UINT16(buf);
- imdPtr->verMin = READ_LE_UINT16(buf + 2);
- imdPtr->framesCount = READ_LE_UINT16(buf + 4);
- imdPtr->x = READ_LE_UINT16(buf + 6);
- imdPtr->y = READ_LE_UINT16(buf + 8);
- imdPtr->width = READ_LE_UINT16(buf + 10);
- imdPtr->height = READ_LE_UINT16(buf + 12);
- imdPtr->field_E = READ_LE_UINT16(buf + 14);
- imdPtr->curFrame = READ_LE_UINT16(buf + 16);
-
- if (imdPtr->fileHandle != 0)
- imdPtr->verMin = 0;
-
- if ((imdPtr->verMin & 0xFF) < 2) {
- warning("IMD version incorrect (%d,%d)", imdPtr->fileHandle, imdPtr->verMin);
+ imdPtr->handle = _vm->_dataIO->readUint16(handle);
+ imdPtr->verMin = _vm->_dataIO->readUint16(handle);
+ imdPtr->framesCount = _vm->_dataIO->readUint16(handle);
+ imdPtr->x = _vm->_dataIO->readUint16(handle);
+ imdPtr->y = _vm->_dataIO->readUint16(handle);
+ imdPtr->width = _vm->_dataIO->readUint16(handle);
+ imdPtr->height = _vm->_dataIO->readUint16(handle);
+ imdPtr->field_E = _vm->_dataIO->readUint16(handle);
+ imdPtr->curFrame = _vm->_dataIO->readUint16(handle);
+
+ if ((imdPtr->handle != 0) || ((imdPtr->verMin & 0xFF) < 2)) {
+ warning("%s: Version incorrect (%d,%X)", buf, imdPtr->handle, imdPtr->verMin);
_vm->_dataIO->closeData(handle);
delete imdPtr;
return 0;
}
+ imdPtr->handle = handle;
imdPtr->surfDesc = surfDesc;
imdPtr->firstFramePos = imdPtr->curFrame;
+ imdPtr->curFrame = 0;
-/*
- imdPtr->field_3A = 0;
if ((imdPtr->verMin & 0x800) && ((flags & 3) != 3))
- imdPtr->field_3A = new Video::Color[256];
-*/
+ imdPtr->extraPalette = new Video::Color[256];
if (flags & 3) {
imdPtr->palette = new Video::Color[256];
+ assert(imdPtr->palette);
_vm->_dataIO->readData(handle, (char *) imdPtr->palette, 768);
- } else {
- imdPtr->palette = 0;
- _vm->_dataIO->seekData(handle, 768, 1);
- }
-
- if ((flags & 3) == 1) {
- palBak = _vm->_global->_pPaletteDesc->vgaPal;
- setAllPalBak = _vm->_global->_setAllPalette;
-
- _vm->_global->_pPaletteDesc->vgaPal = imdPtr->palette;
- _vm->_global->_setAllPalette = true;
- _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
+ } else
+ _vm->_dataIO->seekData(handle, 768, SEEK_CUR);
- _vm->_global->_setAllPalette = setAllPalBak;
- _vm->_global->_pPaletteDesc->vgaPal = palBak;
- }
+ if ((flags & 3) == 1)
+ _vm->_video->setPalette(imdPtr->palette);
if ((imdPtr->verMin & 0xFF) >= 3) {
- _vm->_dataIO->readData(handle, buf, 2);
- imdPtr->stdX = READ_LE_UINT16(buf);
+ imdPtr->stdX = _vm->_dataIO->readUint16(handle);
if (imdPtr->stdX > 1) {
- warning("IMD ListI incorrect (%d)", imdPtr->stdX);
- _vm->_dataIO->closeData(handle);
- delete imdPtr;
+ warning("%s: More than one standard coordinate quad found (%d)",
+ buf, imdPtr->stdX);
+ finishImd(imdPtr);
return 0;
}
if (imdPtr->stdX != 0) {
- _vm->_dataIO->readData(handle, buf, 8);
- imdPtr->stdX = READ_LE_UINT16(buf);
- imdPtr->stdY = READ_LE_UINT16(buf + 2);
- imdPtr->stdWidth = READ_LE_UINT16(buf + 4);
- imdPtr->stdHeight = READ_LE_UINT16(buf + 6);
+ imdPtr->stdX = _vm->_dataIO->readUint16(handle);
+ imdPtr->stdY = _vm->_dataIO->readUint16(handle);
+ imdPtr->stdWidth = _vm->_dataIO->readUint16(handle);
+ imdPtr->stdHeight = _vm->_dataIO->readUint16(handle);
} else
imdPtr->stdX = -1;
} else
imdPtr->stdX = -1;
- imdPtr->framesPos = 0;
if ((imdPtr->verMin & 0xFF) >= 4) {
- _vm->_dataIO->readData(handle, buf, 4);
- byte_31449 = READ_LE_UINT32(buf);
- if (byte_31449 != 0)
+ framesPosPos = _vm->_dataIO->readUint32(handle);
+ if (framesPosPos != 0) {
imdPtr->framesPos = new int32[imdPtr->framesCount];
+ assert(imdPtr->framesPos);
+ }
}
- if (imdPtr->verMin & 0x8000) {
- _vm->_dataIO->readData(handle, buf, 4);
- byte_3144D = READ_LE_UINT32(buf);
- }
+ if (imdPtr->verMin & 0x8000)
+ framesCordsPos = _vm->_dataIO->readUint32(handle);
- if (imdPtr->verMin & 0x4000) { // loc_29C4F
- int16 word_3145B[3];
+ _noSound = true;
+ if (imdPtr->verMin & 0x4000) {
+ _soundFreq = _vm->_dataIO->readUint16(handle);
+ _soundSliceSize = _vm->_dataIO->readUint16(handle);
+ _soundSlicesCount = _vm->_dataIO->readUint16(handle);
- flags &= 0x7F;
- _vm->_dataIO->readData(handle, buf, 6);
- word_3145B[0] = READ_LE_UINT16(buf);
- word_3145B[1] = READ_LE_UINT16(buf + 2);
- word_3145B[2] = READ_LE_UINT16(buf + 4);
+ if (_soundFreq < 0)
+ _soundFreq = -_soundFreq;
- if (word_3145B[0] < 0)
- word_3145B[0] = -word_3145B[0];
- if (word_3145B[2] < 0)
- word_3145B[2] = -word_3145B[2];
+ if (_soundSlicesCount < 0)
+ _soundSlicesCount = -_soundSlicesCount - 1;
- warning("Imd Stub! Sound stuff!");
- return 0;
- } // loc_29E43
+ if (_soundSlicesCount >= 40) {
+ warning("%s: More than 40 sound slices found (%d)",
+ buf, _soundSlicesCount + 1);
+ finishImd(imdPtr);
+ return 0;
+ }
+
+ _soundSliceLength = 1000 / (_soundFreq / _soundSliceSize);
+
+ delete[] _soundBuffer;
+ _soundBuffer = new byte[_soundSliceSize * _soundSlicesCount];
+ assert(_soundBuffer);
+ memset(_soundBuffer, 0, _soundSliceSize * _soundSlicesCount);
+
+ _vm->_snd->stopSound(0);
+ _soundDesc.set(SOUND_SND, SOUND_TOT, _soundBuffer,
+ _soundSliceSize * _soundSlicesCount);
+
+ _curSoundSlice = 0;
+ _soundStage = 1;
+ _noSound = false;
+ }
if (imdPtr->verMin & 0x2000) {
- _vm->_dataIO->readData(handle, buf, 2);
- imdPtr->frameDataSize = READ_LE_UINT16(buf);
+ imdPtr->frameDataSize = _vm->_dataIO->readUint16(handle);
if (imdPtr->frameDataSize == 0) {
- _vm->_dataIO->readData(handle, buf, 8);
- imdPtr->frameDataSize = READ_LE_UINT32(buf);
- imdPtr->vidBufferSize = READ_LE_UINT32(buf + 4);
- } else {
- _vm->_dataIO->readData(handle, buf, 2);
- imdPtr->vidBufferSize = READ_LE_UINT16(buf);
- }
+ imdPtr->frameDataSize = _vm->_dataIO->readUint32(handle);
+ imdPtr->vidBufferSize = _vm->_dataIO->readUint32(handle);
+ } else
+ imdPtr->vidBufferSize = _vm->_dataIO->readUint16(handle);
} else {
imdPtr->frameDataSize = imdPtr->width * imdPtr->height + 500;
- imdPtr->vidBufferSize = 0;
if (!(imdPtr->field_E & 0x100) || (imdPtr->field_E & 0x1000))
- imdPtr->vidBufferSize = imdPtr->width * imdPtr->height + 500;
+ imdPtr->vidBufferSize = imdPtr->frameDataSize;
}
- warning("-> %d, %d", imdPtr->frameDataSize, imdPtr->vidBufferSize);
- if (imdPtr->framesPos != 0) {
- _vm->_dataIO->seekData(handle, byte_31449, 0);
- for (i = 0; i < imdPtr->framesCount; i++) {
- _vm->_dataIO->readData(handle, buf, 4);
- imdPtr->framesPos[i] = READ_LE_UINT32(buf);
- }
+ if (imdPtr->framesPos) {
+ _vm->_dataIO->seekData(handle, framesPosPos, SEEK_SET);
+ for (int i = 0; i < imdPtr->framesCount; i++)
+ imdPtr->framesPos[i] = _vm->_dataIO->readUint32(handle);
}
if (imdPtr->verMin & 0x8000) {
- _vm->_dataIO->seekData(handle, byte_3144D, 0);
+ _vm->_dataIO->seekData(handle, framesCordsPos, SEEK_SET);
imdPtr->frameCoords = new ImdCoord[imdPtr->framesCount];
- for (i = 0; i < imdPtr->framesCount; i++) {
- _vm->_dataIO->readData(handle, buf, 8);
- imdPtr->frameCoords[i].left = READ_LE_UINT16(buf);
- imdPtr->frameCoords[i].top = READ_LE_UINT16(buf + 2);
- imdPtr->frameCoords[i].right = READ_LE_UINT16(buf + 4);
- imdPtr->frameCoords[i].bottom = READ_LE_UINT16(buf + 6);
+ assert(imdPtr->frameCoords);
+ for (int i = 0; i < imdPtr->framesCount; i++) {
+ imdPtr->frameCoords[i].left = _vm->_dataIO->readUint16(handle);
+ imdPtr->frameCoords[i].top = _vm->_dataIO->readUint16(handle);
+ imdPtr->frameCoords[i].right = _vm->_dataIO->readUint16(handle);
+ imdPtr->frameCoords[i].bottom = _vm->_dataIO->readUint16(handle);
}
- } else
- imdPtr->frameCoords = 0;
-
- _vm->_dataIO->seekData(handle, imdPtr->firstFramePos, 0);
- imdPtr->curFrame = 0;
- imdPtr->fileHandle = handle;
- imdPtr->filePos = imdPtr->firstFramePos;
- _frameDataSize = imdPtr->frameDataSize;
- _vidBufferSize = imdPtr->vidBufferSize;
- if (flags & 0x80) {
- imdPtr->verMin |= 0x1000;
- warning("Imd Stub! loadImdFile(), flags & 0x80");
}
+ _vm->_dataIO->seekData(handle, imdPtr->firstFramePos, SEEK_SET);
return imdPtr;
}
-void ImdPlayer::finishImd(ImdPlayer::Imd *imdPtr) {
- if (imdPtr == 0)
+void ImdPlayer::finishImd(ImdPlayer::Imd *&imdPtr) {
+ if (!imdPtr)
return;
-/*
- if (dword_31345 != 0) {
- _vm->_sound->stopSound(0);
- dword_31345 = 0;
- delete off_31461;
- byte_31344 = 0;
- }
-*/
+ _soundDesc.free();
+ if (_soundStage == 2)
+ _vm->_snd->stopSound(0);
- _vm->_dataIO->closeData(imdPtr->fileHandle);
+ _vm->_dataIO->closeData(imdPtr->handle);
- if (imdPtr->frameCoords != 0)
- delete[] imdPtr->frameCoords;
- if (imdPtr->palette != 0)
- delete[] imdPtr->palette;
- if (imdPtr->framesPos != 0)
- delete[] imdPtr->framesPos;
+ delete[] imdPtr->frameCoords;
+ delete[] imdPtr->palette;
+ delete[] imdPtr->framesPos;
+ delete[] imdPtr->extraPalette;
delete imdPtr;
- imdPtr = 0;
}
-int8 ImdPlayer::openImd(const char *path, int16 x, int16 y, int16 repeat, int16 flags) {
- int i;
- int j;
+int8 ImdPlayer::openImd(const char *path, int16 x, int16 y,
+ int16 startFrame, int16 flags) {
const char *src;
byte *vidMem;
SurfaceDesc *surfDesc;
- if (path[0] != 0) {
+ if (!_curImd)
+ _curFile[0] = 0;
+
+ src = strrchr(path, '\\');
+ src = !src ? path : src + 1;
+
+ if ((path[0] != 0) && scumm_stricmp(_curFile, src)) {
+ closeImd();
+
+ _curImd = loadImdFile(path, 0, 3);
if (!_curImd)
- _curFile[0] = 0;
+ return 0;
- src = strrchr(path, '\\');
- src = src == 0 ? path : src+1;
+ _curX = _curImd->x;
+ _curY = _curImd->y;
+ strcpy(_curFile, src);
- if (strcmp(_curFile, src) != 0) {
- closeImd();
+ delete[] _frameData;
+ _frameData = new byte[_curImd->frameDataSize + 500];
+ assert(_frameData);
+ memset(_frameData, 0, _curImd->frameDataSize + 500);
- _curImd = loadImdFile(path, 0, 2);
- if (!_curImd)
- return 0;
+ delete[] _vidBuffer;
+ _vidBuffer = new byte[_curImd->vidBufferSize + 500];
+ assert(_vidBuffer);
+ memset(_vidBuffer, 0, _curImd->vidBufferSize + 500);
- _curX = _curImd->x;
- _curY = _curImd->y;
- strcpy(_curFile, src);
- _frameData = new byte[_frameDataSize + 500];
- _vidBuffer = new byte[_vidBufferSize + 500];
- memset(_frameData, 0, _frameDataSize + 500);
- memset(_vidBuffer, 0, _vidBufferSize + 500);
+ if (!(flags & 0x100)) {
if (_vm->_global->_videoMode == 0x14) {
+
_backSurf = (flags & 0x80) ? 20 : 21;
if (!(_curImd->field_E & 0x100) || (_curImd->field_E & 0x2000)) {
setXY(_curImd, 0, 0);
_curImd->surfDesc =
- _vm->_video->initSurfDesc(0x13, _curImd->width, _curImd->height, 0);
+ _vm->_video->initSurfDesc(0x13,
+ _curImd->width, _curImd->height, 0);
} else {
_curImd->surfDesc = _vm->_draw->_spritesArray[_frontSurf];
if ((x != -1) || (y != -1)) {
@@ -322,44 +309,51 @@ int8 ImdPlayer::openImd(const char *path, int16 x, int16 y, int16 repeat, int16
setXY(_curImd, _curX, _curY);
}
}
+
if (flags & 0x40) {
_curX = x != -1 ? x : _curX;
_curY = y != -1 ? y : _curY;
if (_curImd->surfDesc->_vidMode == 0x14) {
- surfDesc = _vm->_video->initSurfDesc(0x13, _curImd->width, _curImd->height, 0);
- _vm->_video->drawSprite(_vm->_draw->_spritesArray[21], surfDesc, _curX, _curY,
- _curX + _curImd->width - 1, _curY + _curImd->height - 1, 0, 0, 0);
+ surfDesc = _vm->_video->initSurfDesc(0x13,
+ _curImd->width, _curImd->height, 0);
+ _vm->_video->drawSprite(_vm->_draw->_spritesArray[21],
+ surfDesc, _curX, _curY,
+ _curX + _curImd->width - 1, _curY + _curImd->height - 1,
+ 0, 0, 0);
+
vidMem = _curImd->surfDesc->getVidMem();
- for (i = 0; i < _curImd->height; i++)
- for (j = 0; j < _curImd->width; j++, vidMem++) {
+ for (int i = 0; i < _curImd->height; i++)
+ for (int j = 0; j < _curImd->width; j++, vidMem++) {
*(vidMem) = *(surfDesc->getVidMem() +
(j / 4) + (surfDesc->getWidth() / 4 * i));
}
surfDesc = 0;
}
}
+
} else {
if ((x != -1) || (y != -1)) {
- _curX = x != -1 ? x : _curX;
- _curY = y != -1 ? y : _curY;
+ _curX = (x != -1) ? x : _curX;
+ _curY = (y != -1) ? y : _curY;
setXY(_curImd, _curX, _curY);
}
_backSurf = (flags & 0x80) ? 20 : 21;
_curImd->surfDesc = _vm->_draw->_spritesArray[_backSurf];
}
+
}
}
if (!_curImd)
return 0;
- if (repeat == -1) {
+ if (startFrame == -1) {
closeImd();
return 0;
}
- _curX = x != -1 ? x : _curX;
- _curY = y != -1 ? y : _curY;
+ _curX = (x != -1) ? x : _curX;
+ _curY = (y != -1) ? y : _curY;
WRITE_VAR(7, _curImd->framesCount);
@@ -367,16 +361,14 @@ int8 ImdPlayer::openImd(const char *path, int16 x, int16 y, int16 repeat, int16
}
void ImdPlayer::closeImd(void) {
- if (_curImd == 0)
- return;
-
- _curImd->surfDesc = 0;
finishImd(_curImd);
delete[] _frameData;
delete[] _vidBuffer;
+ delete[] _soundBuffer;
_frameData = 0;
_vidBuffer = 0;
+ _soundBuffer = 0;
_curImd = 0;
}
@@ -389,317 +381,23 @@ void ImdPlayer::setXY(ImdPlayer::Imd *imdPtr, int16 x, int16 y) {
imdPtr->stdY = imdPtr->stdY - imdPtr->y + y;
}
- if (imdPtr->frameCoords != 0) {
+ if (imdPtr->frameCoords) {
for (i = 0; i < imdPtr->framesCount; i++) {
- imdPtr->frameCoords[i].left -= imdPtr->frameCoords[i].left - imdPtr->x + x;
- imdPtr->frameCoords[i].top -= imdPtr->frameCoords[i].top - imdPtr->y + y;
- imdPtr->frameCoords[i].right -= imdPtr->frameCoords[i].right - imdPtr->x + x;
- imdPtr->frameCoords[i].bottom -= imdPtr->frameCoords[i].bottom - imdPtr->y + y;
- }
- }
-
- imdPtr->x = x;
- imdPtr->y = y;
-}
-
-void ImdPlayer::play(int16 frame, uint16 palCmd, int16 palStart, int16 palEnd, int16 palFrame, int16 lastFrame) {
- int16 viewRet = 0;
- bool modifiedPal = false;
- SurfaceDesc *surfDescBak;
-
- _vm->_draw->_showCursor = 0;
-
- int8 byte_31344 = 0;
-
- if ((frame < 0) || (frame > lastFrame))
- return;
-
- if ((frame == palFrame) || ((frame == lastFrame) && (palCmd == 8))) { // loc_1C3F0
- modifiedPal = true;
- _vm->_draw->_applyPal = false;
- if (palCmd >= 4) {
- if (palStart != -1)
- memcpy( ((char *) (_vm->_global->_pPaletteDesc->vgaPal)) + palStart * 3,
- ((char *) (_curImd->palette)) + palStart * 3, (palEnd - palStart + 1) * 3);
- else
- memcpy((char *) _vm->_global->_pPaletteDesc->vgaPal, (char *) _curImd->palette, 768);
- }
- }
-
- if (modifiedPal && (palCmd == 8) && (_backSurf == 20))
- _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
-
- if (_curImd->surfDesc->_vidMode == 0x14) {
- if ((_frontSurf == 20) && (_frontMem == _vm->_draw->_spritesArray[20]->getVidMem())) {
- _vm->_draw->_spritesArray[20]->swap(_vm->_draw->_spritesArray[21]);
- viewRet = view(_curImd, frame);
- _vm->_draw->_spritesArray[20]->swap(_vm->_draw->_spritesArray[21]);
- } else
- viewRet = view(_curImd, frame);
- if (_frontSurf == 21) {
- if ((_curImd->frameCoords == 0) || (_curImd->frameCoords[frame].left == -1))
- _vm->_draw->invalidateRect(_curX, _curY,
- _curX + _curImd->width - 1, _curY + _curImd->height - 1);
- else
- _vm->_draw->invalidateRect(_curImd->frameCoords[frame].left,
- _curImd->frameCoords[frame].top, _curImd->frameCoords[frame].right,
- _curImd->frameCoords[frame].bottom);
- }
- } else {
- if ((_curImd->field_E & 0x100) && (_vm->_global->_videoMode == 0x14) &&
- (_frontSurf == 20) && (sub_2C825(_curImd) & 0x8000) && (_backSurf == 21)) {
- surfDescBak = _curImd->surfDesc;
- if (_frontMem == _vm->_draw->_spritesArray[20]->getVidMem())
- _curImd->surfDesc = _vm->_draw->_spritesArray[21];
- else
- _curImd->surfDesc = _vm->_draw->_spritesArray[20];
- setXY(_curImd, _curX, _curY);
- viewRet = view(_curImd, frame);
- _curImd->surfDesc = surfDescBak;
- setXY(_curImd, 0, 0);
- } else {
- viewRet = view(_curImd, frame);
- if (!(viewRet & 0x800)) {
- if (_backSurf == 21) {
- if (_vm->_global->_videoMode == 0x14) {
- if (_frontSurf == 21) {
- _vm->_draw->_frontSurface->swap(_vm->_draw->_spritesArray[21]);
- drawFrame(_curImd, frame, _curX, _curY);
- _vm->_draw->_frontSurface->swap(_vm->_draw->_spritesArray[21]);
- if ((_curImd->frameCoords == 0) || (_curImd->frameCoords[frame].left == -1))
- _vm->_draw->invalidateRect(_curX, _curY, _curX + _curImd->width - 1,
- _curY + _curImd->height - 1);
- else
- _vm->_draw->invalidateRect(_curImd->frameCoords[frame].left,
- _curImd->frameCoords[frame].top, _curImd->frameCoords[frame].right,
- _curImd->frameCoords[frame].bottom);
- } else {
- if (_frontMem == _vm->_draw->_spritesArray[20]->getVidMem()) { // loc_1C68D
- _vm->_draw->_frontSurface->swap(_vm->_draw->_spritesArray[21]);
- drawFrame(_curImd, frame, _curX, _curY);
- _vm->_draw->_frontSurface->swap(_vm->_draw->_spritesArray[21]);
- } else
- drawFrame(_curImd, frame, _curX, _curY);
- }
- } else {
- if ((_curImd->frameCoords == 0) || (_curImd->frameCoords[frame].left == -1))
- _vm->_draw->invalidateRect(_curX, _curY, _curX + _curImd->width - 1,
- _curY + _curImd->height - 1);
- else
- _vm->_draw->invalidateRect(_curImd->frameCoords[frame].left,
- _curImd->frameCoords[frame].top, _curImd->frameCoords[frame].right,
- _curImd->frameCoords[frame].bottom);
- }
- } else
- if (_vm->_global->_videoMode == 0x14)
- drawFrame(_curImd, frame, _curX, _curY);
- }
- }
- }
-
- if (modifiedPal && (palCmd == 16)) {
- if ((_vm->_draw->_spritesArray[20] != _vm->_draw->_spritesArray[21]) && (_backSurf == 21))
- _vm->_video->drawSprite(_vm->_draw->_spritesArray[21],
- _vm->_draw->_spritesArray[20], 0, 0,
- _vm->_draw->_spritesArray[21]->getWidth() - 1,
- _vm->_draw->_spritesArray[21]->getHeight() - 1, 0, 0, 0);
- _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, -2, 0);
- _vm->_draw->_noInvalidated = true;
- }
- if (modifiedPal && (palCmd == 8) && (_backSurf == 21))
- _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
-
- if (!(viewRet & 0x800)) {
- if (_vm->_draw->_cursorIndex == -1) {
- if (_frontSurf == 20) {
- if (_frontMem == _vm->_draw->_spritesArray[20]->getVidMem())
- _frontMem = _vm->_draw->_spritesArray[21]->getVidMem();
- else
- _frontMem = _vm->_draw->_spritesArray[20]->getVidMem();
- warning("GOB2 Stub! sub_1BC3A(_frontMem);");
- } else
- _vm->_draw->blitInvalidated();
- } else
- _vm->_draw->animateCursor(-1);
- }
-
- if (modifiedPal && ((palCmd == 2) || (palCmd == 4)))
- _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, -2, 0);
-
- // To allow quitting, etc. during IMDs
- _vm->_util->processInput();
- if (_vm->_quitRequested)
- return;
-
- if (byte_31344 != 2) {
- if (viewRet & 0x800) {
- if (_frameDelay == 0)
- _vm->_util->delay(30);
- else {
- _frameDelay -= 30;
- if (_frameDelay < 0)
- _frameDelay = 0;
- }
- } else
- _vm->_util->waitEndFrame();
- }
- _vm->_inter->animPalette();
-}
-
-int16 ImdPlayer::view(ImdPlayer::Imd *imdPtr, int16 frame) {
- int16 x;
- int16 y;
- int16 width;
- int16 height;
- int16 retVal;
- uint32 tmp;
- char buf[4];
-
- int8 var_4;
- int32 var_12 = 0;
-
- // .---
- int16 word_31451 = 0;
- int8 byte_31344 = 0;
- int8 byte_2DA60 = 0;
- int16 word_2DA61 = -1;
- // '---
-
- word_31451 = 0;
-
- if (imdPtr == 0)
- return (int16)0x8000;
-
- retVal = 0;
- var_4 = 0;
-
- if (frame != imdPtr->curFrame) {
- retVal |= 0x2000;
- if (frame == 0)
- imdPtr->filePos = imdPtr->firstFramePos;
- else if (frame == 1) {
- imdPtr->filePos = imdPtr->firstFramePos;
- _vm->_dataIO->seekData(imdPtr->fileHandle, imdPtr->filePos, 0);
- _vm->_dataIO->readData(imdPtr->fileHandle, buf, 2);
- tmp = READ_LE_UINT16(buf);
- imdPtr->filePos += tmp + 4;
- } else if (imdPtr->framesPos != 0)
- imdPtr->filePos = imdPtr->framesPos[frame];
- else
- error("Image %d inaccessible in IMD", frame);
- imdPtr->curFrame = frame;
- _vm->_dataIO->seekData(imdPtr->fileHandle, imdPtr->filePos, 0);
- }
-
- x = imdPtr->x;
- y = imdPtr->y;
- width = imdPtr->width;
- height = imdPtr->height;
-
- do {
- if (frame != 0) {
- if (imdPtr->stdX != -1) {
- imdPtr->x = imdPtr->stdX;
- imdPtr->y = imdPtr->stdY;
- imdPtr->width = imdPtr->stdWidth;
- imdPtr->height = imdPtr->stdHeight;
- retVal |= 0x1000;
- }
- if ((imdPtr->frameCoords != 0) && (imdPtr->frameCoords[frame].left != -1)) {
- var_4 |= 0x400;
- imdPtr->x = imdPtr->frameCoords[frame].left;
- imdPtr->y = imdPtr->frameCoords[frame].top;
- imdPtr->width = imdPtr->frameCoords[frame].right - imdPtr->x + 1;
- imdPtr->height = imdPtr->frameCoords[frame].bottom - imdPtr->y + 1;
+ if (imdPtr->frameCoords[i].left != -1) {
+ imdPtr->frameCoords[i].left -=
+ imdPtr->frameCoords[i].left - imdPtr->x + x;
+ imdPtr->frameCoords[i].top -=
+ imdPtr->frameCoords[i].top - imdPtr->y + y;
+ imdPtr->frameCoords[i].right -=
+ imdPtr->frameCoords[i].right - imdPtr->x + x;
+ imdPtr->frameCoords[i].bottom -=
+ imdPtr->frameCoords[i].bottom - imdPtr->y + y;
}
}
-
- _vm->_dataIO->readData(imdPtr->fileHandle, buf, 2);
- tmp = READ_LE_UINT16(buf);
-
- imdPtr->filePos += 2;
-
- if ((tmp & 0xFFF8) == 0xFFF0) {
- if (tmp == 0xFFF0) {
- _vm->_dataIO->readData(imdPtr->fileHandle, buf, 2);
- tmp = READ_LE_UINT16(buf);
- if (var_4 == 0)
- word_31451 = tmp;
- _vm->_dataIO->readData(imdPtr->fileHandle, buf, 2);
- tmp = READ_LE_UINT16(buf);
- imdPtr->filePos += 4;
- } else if (tmp == 0xFFF1) {
- retVal = (int16)0x8000;
- continue;
- } else if (tmp == 0xFFF2) {
- _vm->_dataIO->readData(imdPtr->fileHandle, buf, 2);
- tmp = READ_LE_UINT16(buf);
- imdPtr->filePos += 2;
- _vm->_dataIO->seekData(imdPtr->fileHandle, tmp, 1);
- imdPtr->filePos += tmp;
- retVal = (int16)0x8000;
- continue;
- } else if (tmp == 0xFFF3) {
- _vm->_dataIO->readData(imdPtr->fileHandle, buf, 4);
- tmp = READ_LE_UINT32(buf);
- imdPtr->filePos += 4;
- _vm->_dataIO->seekData(imdPtr->fileHandle, tmp, 1);
- imdPtr->filePos += tmp;
- retVal = (int16)0x8000;
- continue;
- }
- }
- if (byte_31344 != 0) {
- if ((var_4 == 0) && (_vm->_global->_soundFlags & 0x14) && (byte_31344 == 2)) { // loc_2A503
- var_12 = _vm->_util->getTimeKey();
- warning("GOB2 Stub! view, IMD sound stuff");
- }
- }
- var_4 = 0;
- if (tmp == 0xFFFD) {
- _vm->_dataIO->readData(imdPtr->fileHandle, buf, 2);
- frame = READ_LE_UINT16(buf);
- if ((imdPtr->framesPos != 0) && (byte_2DA60 == 0)) {
- word_2DA61 = frame;
- imdPtr->filePos = imdPtr->framesPos[frame];
- _vm->_dataIO->seekData(imdPtr->fileHandle, imdPtr->filePos, 0);
- var_4 = 1;
- retVal |= 0x200;
- imdPtr->curFrame = frame;
- } else
- imdPtr->filePos += 2;
- continue;
- }
- if (tmp != 0) {
- imdPtr->filePos += tmp + 2;
- if (byte_2DA60 != 0) {
- _vm->_dataIO->seekData(imdPtr->fileHandle, tmp + 2, 1);
- } else {
- _vm->_dataIO->readData(imdPtr->fileHandle, (char *) _frameData, tmp + 2);
- retVal |= *_frameData;
- if (imdPtr->surfDesc == 0)
- continue;
- if (imdPtr->surfDesc->_vidMode != 0x14)
- renderframe(imdPtr);
- else
- warning("GOB2 Stub! viedImd, sub_2C69A(imdPtr);");
- }
- } else
- retVal |= 0x800;
- } while (var_4 != 0);
-
- if (byte_2DA60 != 0) {
- byte_2DA60 = 0;
- retVal |= 0x100;
}
imdPtr->x = x;
imdPtr->y = y;
- imdPtr->width = width;
- imdPtr->height = height;
- imdPtr->curFrame++;
-
- return retVal;
}
void ImdPlayer::drawFrame(Imd *imdPtr, int16 frame, int16 x, int16 y,
@@ -710,7 +408,7 @@ void ImdPlayer::drawFrame(Imd *imdPtr, int16 frame, int16 x, int16 y,
if (frame == 0)
_vm->_video->drawSprite(imdPtr->surfDesc, dest, 0, 0,
imdPtr->width - 1, imdPtr->height - 1, x, y, 1);
- else if ((imdPtr->frameCoords != 0) && (imdPtr->frameCoords[frame].left != -1))
+ else if (imdPtr->frameCoords && (imdPtr->frameCoords[frame].left != -1))
_vm->_video->drawSprite(imdPtr->surfDesc, dest,
imdPtr->frameCoords[frame].left, imdPtr->frameCoords[frame].top,
imdPtr->frameCoords[frame].right, imdPtr->frameCoords[frame].bottom,
@@ -725,12 +423,9 @@ void ImdPlayer::drawFrame(Imd *imdPtr, int16 frame, int16 x, int16 y,
imdPtr->width - 1, imdPtr->height - 1, x, y, 0);
}
-void ImdPlayer::renderframe(Imd *imdPtr) {
- int i;
- int16 imdX;
- int16 imdY;
- int16 imdW;
- int16 imdH;
+void ImdPlayer::renderFrame(Imd *imdPtr) {
+ int16 imdX, imdY;
+ int16 imdW, imdH;
int16 sW;
uint16 pixCount, pixWritten;
uint8 type;
@@ -738,7 +433,6 @@ void ImdPlayer::renderframe(Imd *imdPtr) {
byte *imdVidMemBak;
byte *dataPtr = 0;
byte *srcPtr = 0;
- byte *srcPtrBak = 0;
dataPtr = (byte *) _frameData;
imdX = imdPtr->x;
@@ -751,14 +445,13 @@ void ImdPlayer::renderframe(Imd *imdPtr) {
type = *dataPtr++;
srcPtr = dataPtr;
- if (type & 0x10) {
+ if (type & 0x10) { // Palette data
type ^= 0x10;
- dataPtr++; // => 0x3C8 |_ palette
- dataPtr += 48; // => 0x3C9 | stuff
+ dataPtr += 49;
}
srcPtr = dataPtr;
- if (type & 0x80) {
+ if (type & 0x80) { // Frame data is compressed
srcPtr = (byte *) _vidBuffer;
type &= 0x7F;
if ((type == 2) && (imdW == sW)) {
@@ -768,27 +461,26 @@ void ImdPlayer::renderframe(Imd *imdPtr) {
frameUncompressor(srcPtr, dataPtr);
}
- if (type == 2) {
- for (i = 0; i < imdH; i++) {
+ if (type == 2) { // Whole block
+ for (int i = 0; i < imdH; i++) {
memcpy(imdVidMem, srcPtr, imdW);
srcPtr += imdW;
imdVidMem += sW;
}
- } else if (type == 1) {
+ } else if (type == 1) { // Sparse block
imdVidMemBak = imdVidMem;
- for (i = 0; i < imdH; i++) {
+ for (int i = 0; i < imdH; i++) {
pixWritten = 0;
while (pixWritten < imdW) {
pixCount = *srcPtr++;
- if (pixCount & 0x80) {
- pixCount = (pixCount & 0x7F) + 1;
- // Just to be safe
- pixCount = (pixWritten + pixCount) > imdW ? imdW - pixWritten : pixCount;
- pixWritten += pixCount;
+ if (pixCount & 0x80) { // data
+ pixCount = MIN((pixCount & 0x7F) + 1, imdW - pixWritten);
memcpy(imdVidMem, srcPtr, pixCount);
+
+ pixWritten += pixCount;
imdVidMem += pixCount;
srcPtr += pixCount;
- } else {
+ } else { // "hole"
pixCount = (pixCount + 1) % 256;
pixWritten += pixCount;
imdVidMem += pixCount;
@@ -797,33 +489,45 @@ void ImdPlayer::renderframe(Imd *imdPtr) {
imdVidMemBak += sW;
imdVidMem = imdVidMemBak;
}
- } else if (type == 0x42) { // loc_2AFC4
- warning("=> type == 0x42");
- } else if ((type & 0xF) == 2) { // loc_2AFEC
- warning("=> (type & 0xF) == 2");
- } else { // loc_2B021
- srcPtrBak = srcPtr;
- for (i = 0; i < imdH; i += 2) {
+ } else if (type == 0x42) { // Whole quarter-wide block
+ for (int i = 0; i < imdH; i++) {
+ imdVidMemBak = imdVidMem;
+
+ for (int j = 0; j < imdW; j += 4, imdVidMem += 4, srcPtr++)
+ memset(imdVidMem, *srcPtr, 4);
+
+ imdVidMemBak += sW;
+ imdVidMem = imdVidMemBak;
+ }
+ } else if ((type & 0xF) == 2) { // Whole half-high block
+ for (; imdH > 1; imdH -= 2, imdVidMem += sW + sW, srcPtr += imdW) {
+ memcpy(imdVidMem, srcPtr, imdW);
+ memcpy(imdVidMem + sW, srcPtr, imdW);
+ }
+ if (imdH == -1)
+ memcpy(imdVidMem, srcPtr, imdW);
+ } else { // Sparse half-high block
+ imdVidMemBak = imdVidMem;
+ for (int i = 0; i < imdH; i += 2) {
pixWritten = 0;
while (pixWritten < imdW) {
pixCount = *srcPtr++;
- if (pixCount & 0x80) {
- pixCount = (pixCount & 0x7F) + 1;
- // Just to be safe
- pixCount = (pixWritten + pixCount) > imdW ? imdW - pixWritten : pixCount;
- pixWritten += pixCount;
+ if (pixCount & 0x80) { // data
+ pixCount = MIN((pixCount & 0x7F) + 1, imdW - pixWritten);
memcpy(imdVidMem, srcPtr, pixCount);
memcpy(imdVidMem + sW, srcPtr, pixCount);
+
+ pixWritten += pixCount;
imdVidMem += pixCount;
srcPtr += pixCount;
- } else {
+ } else { // "hole"
pixCount = (pixCount + 1) % 256;
pixWritten += pixCount;
imdVidMem += pixCount;
}
}
- srcPtrBak += sW + sW;
- srcPtr = srcPtrBak;
+ imdVidMemBak += sW + sW;
+ imdVidMem = imdVidMemBak;
}
}
}
@@ -831,8 +535,8 @@ void ImdPlayer::renderframe(Imd *imdPtr) {
void ImdPlayer::frameUncompressor(byte *dest, byte *src) {
int i;
byte buf[4370];
- int16 chunkLength;
- int16 frameLength;
+ uint16 chunkLength;
+ uint16 frameLength;
uint16 bufPos1;
uint16 bufPos2;
uint16 tmp;
@@ -842,13 +546,16 @@ void ImdPlayer::frameUncompressor(byte *dest, byte *src) {
frameLength = READ_LE_UINT16(src);
src += 4;
- bufPos1 = 4078;
- mode = 0; // 275h (jnz +2)
+
if ((READ_LE_UINT16(src) == 0x1234) && (READ_LE_UINT16(src + 2) == 0x5678)) {
src += 4;
bufPos1 = 273;
mode = 1; // 123Ch (cmp al, 12h)
+ } else {
+ bufPos1 = 4078;
+ mode = 0; // 275h (jnz +2)
}
+
memset(buf, 32, bufPos1);
chunkCount = 1;
chunkBitField = 0;
@@ -874,99 +581,644 @@ void ImdPlayer::frameUncompressor(byte *dest, byte *src) {
src += 2;
chunkLength = ((tmp & 0xF00) >> 8) + 3;
- if ((mode && ((chunkLength & 0xFF) == 0x12)) || (!mode && (chunkLength == 0)))
+ if ((mode && ((chunkLength & 0xFF) == 0x12)) ||
+ (!mode && (chunkLength == 0)))
chunkLength = *src++ + 0x12;
bufPos2 = (tmp & 0xFF) + ((tmp >> 4) & 0x0F00);
- if (((tmp + chunkLength) >= 4096) || ((chunkLength + bufPos1) >= 4096)) {
+ if (((tmp + chunkLength) >= 4096) ||
+ ((chunkLength + bufPos1) >= 4096)) {
+
for (i = 0; i < chunkLength; i++, dest++) {
*dest = buf[bufPos2];
buf[bufPos1] = buf[bufPos2];
bufPos1 = (bufPos1 + 1) % 4096;
bufPos2 = (bufPos2 + 1) % 4096;
}
- frameLength -= chunkLength;
- } else if (((tmp + chunkLength) < bufPos1) || ((chunkLength + bufPos1) < bufPos2)) {
+
+ } else if (((tmp + chunkLength) < bufPos1) ||
+ ((chunkLength + bufPos1) < bufPos2)) {
+
memcpy(dest, buf + bufPos2, chunkLength);
- dest += chunkLength;
memmove(buf + bufPos1, buf + bufPos2, chunkLength);
+
+ dest += chunkLength;
bufPos1 += chunkLength;
bufPos2 += chunkLength;
- frameLength -= chunkLength;
+
} else {
+
for (i = 0; i < chunkLength; i++, dest++, bufPos1++, bufPos2++) {
*dest = buf[bufPos2];
buf[bufPos1] = buf[bufPos2];
}
- frameLength -= chunkLength;
+
}
+ frameLength -= chunkLength;
+
}
}
-void ImdPlayer::play(const char *path, int16 x, int16 y, int16 startFrame, int16 frames,
- bool fade, bool interruptible) {
+void ImdPlayer::play(const char *path, int16 x, int16 y, bool interruptible) {
+ int16 mouseX;
+ int16 mouseY;
+ int16 buttons;
+
+ _vm->_util->setFrameRate(12);
+ if(!openImd(path, x, y, 0, 2))
+ return;
+
+ _vm->_video->fillRect(_vm->_draw->_frontSurface, x, y,
+ x + _curImd->width - 1, y + _curImd->height - 1, 0);
+
+ for (int i = 0; i < _curImd->framesCount; i++) {
+ play(i, 4, 0, 255, 0, _curImd->framesCount - 1);
+
+ if (_vm->_quitRequested || (interruptible &&
+ (_vm->_game->checkKeys(&mouseX, &mouseY, &buttons, 0) == 0x11B)))
+ break;
+ }
+
+ closeImd();
+}
+
+void ImdPlayer::play(const char *path, int16 x, int16 y, int16 startFrame,
+ int16 frames, bool fade, bool interruptible) {
int16 mouseX;
int16 mouseY;
int16 buttons = 0;
- int curFrame;
int endFrame;
- int backFrame;
_vm->_util->setFrameRate(12);
- openImd(path, 0, 0, 0, 0);
- _vm->_video->fillRect(_vm->_draw->_frontSurface, x, y, x + _curImd->width - 1,
- y + _curImd->height - 1, 0);
+ if(!openImd(path, x, y, 0, 0))
+ return;
+
+ _vm->_video->fillRect(_vm->_draw->_frontSurface, x, y,
+ x + _curImd->width - 1, y + _curImd->height - 1, 0);
if (fade)
_vm->_palAnim->fade(0, -2, 0);
endFrame = frames > 0 ? frames : _curImd->framesCount;
- for (curFrame = 0; curFrame < endFrame; curFrame++) {
- view(_curImd, curFrame);
- drawFrame(_curImd, curFrame, x, y);
+ for (int i = startFrame; i < endFrame; i++) {
+ view(_curImd, i);
+ drawFrame(_curImd, i, x, y);
if (fade) {
_vm->_palAnim->fade(_vm->_global->_pPaletteDesc, -2, 0);
fade = false;
}
- _vm->_video->waitRetrace(_vm->_global->_videoMode);
- if ((interruptible && (_vm->_game->checkKeys(&mouseX, &mouseY, &buttons, 0) == 0x11B)) ||
- _vm->_quitRequested) {
+ _vm->_video->waitRetrace();
+
+ if (_vm->_quitRequested || (interruptible &&
+ (_vm->_game->checkKeys(&mouseX, &mouseY, &buttons, 0) == 0x11B))) {
_vm->_palAnim->fade(0, -2, 0);
_vm->_video->clearSurf(_vm->_draw->_frontSurface);
memset((char *) _vm->_draw->_vgaPalette, 0, 768);
+
WRITE_VAR(4, buttons);
WRITE_VAR(0, 0x11B);
WRITE_VAR(57, (uint32) -1);
break;
}
+
_vm->_util->waitEndFrame();
}
+
if (frames < 0) {
endFrame = _curImd->framesCount + frames;
- for (curFrame = _curImd->framesCount - 1; curFrame >= endFrame; curFrame--) {
- for (backFrame = 0; backFrame <= curFrame; backFrame++)
- view(_curImd, backFrame);
- drawFrame(_curImd, curFrame, x, y);
- _vm->_video->waitRetrace(_vm->_global->_videoMode);
- if ((interruptible && (_vm->_game->checkKeys(&mouseX, &mouseY, &buttons, 0) == 0x11B)) ||
- _vm->_quitRequested) {
+ for (int i = _curImd->framesCount - 1; i >= endFrame; i--) {
+ seekFrame(_curImd, i, SEEK_SET, true);
+ drawFrame(_curImd, i, x, y);
+ _vm->_video->waitRetrace();
+
+ if (_vm->_quitRequested || (interruptible &&
+ (_vm->_game->checkKeys(&mouseX, &mouseY, &buttons, 0) == 0x11B))) {
_vm->_palAnim->fade(0, -2, 0);
_vm->_video->clearSurf(_vm->_draw->_frontSurface);
memset((char *) _vm->_draw->_vgaPalette, 0, 768);
+
WRITE_VAR(4, buttons);
WRITE_VAR(0, 0x11B);
WRITE_VAR(57, (uint32) -1);
break;
}
+
_vm->_util->waitEndFrame();
}
}
+
closeImd();
}
-int16 ImdPlayer::sub_2C825(Imd *imdPtr) {
- warning("GOB2 Stub! sub_2C825()");
- return 0;
+void ImdPlayer::play(int16 frame, uint16 palCmd,
+ int16 palStart, int16 palEnd, int16 palFrame, int16 lastFrame) {
+ uint32 viewRet = 0;
+ SurfaceDesc *surfDescBak;
+ bool modifiedPal = false;
+
+ _vm->_draw->_showCursor = 0;
+
+ if ((frame < 0) || (frame > lastFrame))
+ return;
+
+ palCmd &= 0x3F;
+ if ((frame == palFrame) || ((frame == lastFrame) && (palCmd == 8))) {
+ modifiedPal = true;
+ _vm->_draw->_applyPal = true;
+
+ if (palCmd >= 4)
+ copyPalette(palStart, palEnd);
+ }
+
+ if (modifiedPal && (palCmd == 8) && (_backSurf == 20))
+ _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
+
+ if (_curImd->surfDesc) {
+ if (_curImd->surfDesc->_vidMode == 0x14) {
+
+ if ((_frontMem == _vm->_draw->_frontSurface->getVidMem()) &&
+ (_frontSurf == 20)) {
+ _vm->_draw->_frontSurface->swap(_vm->_draw->_backSurface);
+ viewRet = view(_curImd, frame);
+ _vm->_draw->_frontSurface->swap(_vm->_draw->_backSurface);
+ } else
+ viewRet = view(_curImd, frame);
+
+ if (_frontSurf == 21)
+ _vm->_draw->invalidateRect(_left, _top, _right, _bottom);
+
+ } else {
+ if ((_curImd->field_E & 0x100) &&
+ (_vm->_global->_videoMode == 0x14) &&
+ (_frontSurf == 20) &&
+ (checkFrameType(_curImd, frame) & 0x8000) &&
+ (_backSurf == 21)) {
+
+ surfDescBak = _curImd->surfDesc;
+ if (_frontMem == _vm->_draw->_spritesArray[20]->getVidMem())
+ _curImd->surfDesc = _vm->_draw->_spritesArray[21];
+ else
+ _curImd->surfDesc = _vm->_draw->_spritesArray[20];
+ setXY(_curImd, _curX, _curY);
+ viewRet = view(_curImd, frame);
+ _curImd->surfDesc = surfDescBak;
+ setXY(_curImd, 0, 0);
+
+ } else {
+ viewRet = view(_curImd, frame);
+ if (!(viewRet & 0x800))
+ drawFrame(frame);
+ }
+ }
+ } else
+ viewRet = view(_curImd, frame);
+
+ if (modifiedPal && (palCmd == 16)) {
+ if (_backSurf == 21)
+ _vm->_draw->forceBlit();
+ _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, -2, 0);
+ _vm->_draw->_noInvalidated = true;
+ }
+
+ if (viewRet & 0x10) {
+ copyPalette(palStart, palEnd);
+
+ if (_backSurf == 20)
+ _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
+ else
+ _vm->_draw->_applyPal = true;
+ }
+
+ if (modifiedPal && (palCmd == 8) && (_backSurf == 21))
+ _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
+
+ if (!(viewRet & 0x800)) {
+ if (_vm->_draw->_cursorIndex == -1) {
+ if (_frontSurf == 20)
+ flipFrontMem();
+ else
+ _vm->_draw->blitInvalidated();
+ } else
+ _vm->_draw->animateCursor(-1);
+ }
+
+ if (modifiedPal && ((palCmd == 2) || (palCmd == 4)))
+ _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, -2, 0);
+
+ // To allow quitting, etc. during IMDs
+ _vm->_util->processInput();
+ if (_vm->_quitRequested)
+ return;
+
+ if (_soundStage != 2) {
+ if (viewRet & 0x800) {
+ if (_frameDelay == 0)
+ _vm->_util->delay(30);
+ else {
+ _frameDelay -= 30;
+ if (_frameDelay < 0)
+ _frameDelay = 0;
+ }
+ } else
+ _vm->_util->waitEndFrame();
+ }
+
+ _vm->_inter->animPalette();
+}
+
+inline void ImdPlayer::drawFrame(int16 frame) {
+ if (_backSurf == 21) {
+
+ if (_vm->_global->_videoMode == 0x14) {
+ if (_frontSurf == 21) {
+ _vm->_draw->_frontSurface->swap(_vm->_draw->_spritesArray[21]);
+ drawFrame(_curImd, frame, _curX, _curY);
+ _vm->_draw->_frontSurface->swap(_vm->_draw->_spritesArray[21]);
+ _vm->_draw->invalidateRect(_curX + _left, _curY + _top,
+ _curX + _right, _curY + _bottom);
+ } else {
+ if (_frontMem == _vm->_draw->_spritesArray[20]->getVidMem()) {
+ _vm->_draw->_frontSurface->swap(_vm->_draw->_spritesArray[21]);
+ drawFrame(_curImd, frame, _curX, _curY);
+ _vm->_draw->_frontSurface->swap(_vm->_draw->_spritesArray[21]);
+ } else
+ drawFrame(_curImd, frame, _curX, _curY);
+ }
+ } else
+ _vm->_draw->invalidateRect(_left, _top, _right, _bottom);
+
+ } else if (_vm->_global->_videoMode == 0x14)
+ drawFrame(_curImd, frame, _curX, _curY);
+}
+
+inline void ImdPlayer::copyPalette(int16 palStart, int16 palEnd) {
+ if (palStart == -1)
+ memcpy((char *) _vm->_global->_pPaletteDesc->vgaPal,
+ (char *) _curImd->palette, 768);
+ else
+ memcpy(((char *) (_vm->_global->_pPaletteDesc->vgaPal)) +
+ palStart * 3, ((char *) (_curImd->palette)) + palStart * 3,
+ (palEnd - palStart + 1) * 3);
+}
+
+inline void ImdPlayer::flipFrontMem() {
+ if (_frontMem == _vm->_draw->_frontSurface->getVidMem())
+ _frontMem = _vm->_draw->_backSurface->getVidMem();
+ else
+ _frontMem = _vm->_draw->_frontSurface->getVidMem();
+}
+
+uint16 ImdPlayer::checkFrameType(Imd *imdPtr, int16 frame) {
+ uint16 retVal = 0;
+ uint32 posBak;
+ uint32 tmp;
+ uint16 cmd;
+ int16 frameBak;
+
+ if (!imdPtr)
+ return 0x8000;
+
+ posBak = _vm->_dataIO->getPos(imdPtr->handle);
+ frameBak = imdPtr->curFrame;
+
+ if (imdPtr->curFrame != frame) {
+ retVal |= 0x2000;
+ seekFrame(imdPtr, frame, SEEK_SET);
+ }
+
+ do {
+ if (frame != 0) {
+ if (imdPtr->stdX != -1)
+ retVal |= 0x1000;
+ if (imdPtr->frameCoords && (imdPtr->frameCoords[frame].left != -1))
+ retVal |= 0x400;
+ }
+
+ cmd = _vm->_dataIO->readUint16(imdPtr->handle);
+
+ if ((cmd & 0xFFF8) == 0xFFF0) {
+ if (cmd == 0xFFF0) {
+ _vm->_dataIO->seekData(imdPtr->handle, 2, SEEK_CUR);
+ cmd = _vm->_dataIO->readUint16(imdPtr->handle);
+ }
+
+ if (cmd == 0xFFF1) {
+ retVal = 0x8000;
+ continue;
+ } else if (cmd == 0xFFF2) { // Skip (16 bit)
+ cmd = _vm->_dataIO->readUint16(imdPtr->handle);
+ _vm->_dataIO->seekData(imdPtr->handle, cmd, SEEK_CUR);
+ retVal = 0x8000;
+ continue;
+ } else if (cmd == 0xFFF3) { // Skip (32 bit)
+ tmp = _vm->_dataIO->readUint32(imdPtr->handle);
+ _vm->_dataIO->seekData(imdPtr->handle, cmd, SEEK_CUR);
+ retVal = 0x8000;
+ continue;
+ }
+ }
+
+ // Jump to frame
+ if (cmd == 0xFFFD) {
+ frame = _vm->_dataIO->readUint16(imdPtr->handle);
+ if (imdPtr->framesPos) {
+ _vm->_dataIO->seekData(imdPtr->handle,
+ imdPtr->framesPos[frame], SEEK_SET);
+ retVal |= 0x200;
+ continue;
+ }
+ break;
+ }
+
+ // Next sound slice data
+ if (cmd == 0xFF00) {
+ _vm->_dataIO->seekData(imdPtr->handle,
+ _soundSliceSize, SEEK_CUR);
+ cmd = _vm->_dataIO->readUint16(imdPtr->handle);
+ // Initial sound data (all slices)
+ } else if (cmd == 0xFF01) {
+ _vm->_dataIO->seekData(imdPtr->handle,
+ _soundSliceSize * _soundSlicesCount, SEEK_CUR);
+ cmd = _vm->_dataIO->readUint16(imdPtr->handle);
+ }
+
+ // Frame video data
+ if (cmd != 0) {
+ _vm->_dataIO->readData(imdPtr->handle, (char *) _frameData, 5);
+ retVal |= _frameData[0];
+ } else
+ retVal |= 0x800;
+
+ break;
+
+ } while (true);
+
+ _vm->_dataIO->seekData(imdPtr->handle, posBak, SEEK_SET);
+ imdPtr->curFrame = frameBak;
+ return retVal;
+}
+
+void ImdPlayer::seekFrame(Imd *imdPtr, int16 frame, int16 from, bool restart) {
+ uint32 framePos;
+
+ if (!imdPtr)
+ return;
+
+ if (from == SEEK_CUR)
+ frame += imdPtr->curFrame;
+ else if (from == SEEK_END)
+ frame = imdPtr->framesCount - frame - 1;
+
+ if (frame >= imdPtr->framesCount)
+ return;
+
+ if (frame == 0) {
+ framePos = imdPtr->firstFramePos;
+ } else if (frame == 1) {
+ framePos = imdPtr->firstFramePos;
+ _vm->_dataIO->seekData(imdPtr->handle, framePos, SEEK_SET);
+ framePos += _vm->_dataIO->readUint16(imdPtr->handle) + 4;
+ } else if (imdPtr->framesPos) {
+ framePos = imdPtr->framesPos[frame];
+ } else if (restart && (_soundStage == 0)) {
+ for (int i = 0; i <= frame; i++)
+ view(_curImd, i);
+ } else
+ error("%s: Frame %d is not directly accessible", _curFile, frame);
+
+ _vm->_dataIO->seekData(imdPtr->handle, framePos, SEEK_SET);
+ imdPtr->curFrame = frame;
+}
+
+uint32 ImdPlayer::view(Imd *imdPtr, int16 frame) {
+ uint32 retVal = 0;
+ uint32 cmd = 0;
+ int16 xBak, yBak, heightBak, widthBak;
+ bool hasNextCmd = false;
+ bool startSound = false;
+
+ if (!imdPtr)
+ return 0x8000;
+
+ if (frame != imdPtr->curFrame) {
+ retVal |= 0x2000;
+ seekFrame(imdPtr, frame, SEEK_SET);
+ }
+
+ _left = xBak = imdPtr->x;
+ _top = yBak = imdPtr->y;
+ _bottom = heightBak= imdPtr->height;
+ _right = widthBak = imdPtr->width;
+
+ if ((frame == 0) && (imdPtr->verMin & 0x800))
+ _vm->_video->setPalette(imdPtr->palette);
+
+ do {
+ if (frame != 0) {
+ if (imdPtr->stdX != -1) {
+ _left = imdPtr->x = imdPtr->stdX;
+ _top = imdPtr->y = imdPtr->stdY;
+ _right = imdPtr->width = imdPtr->stdWidth;
+ _bottom = imdPtr->height = imdPtr->stdHeight;
+ _right += _left - 1;
+ _bottom += _top - 1;
+ retVal |= 0x1000;
+ }
+ if (imdPtr->frameCoords &&
+ (imdPtr->frameCoords[frame].left != -1)) {
+ _left = imdPtr->x = imdPtr->frameCoords[frame].left;
+ _top = imdPtr->y = imdPtr->frameCoords[frame].top;
+ _right = imdPtr->width =
+ imdPtr->frameCoords[frame].right - imdPtr->x + 1;
+ _bottom = imdPtr->height =
+ imdPtr->frameCoords[frame].bottom - imdPtr->y + 1;
+ _right += _left - 1;
+ _bottom += _top - 1;
+ retVal |= 0x400;
+ }
+ }
+
+ cmd = _vm->_dataIO->readUint16(imdPtr->handle);
+
+ if ((cmd & 0xFFF8) == 0xFFF0) {
+ if (cmd == 0xFFF0) {
+ _vm->_dataIO->seekData(imdPtr->handle, 2, SEEK_CUR);
+ cmd = _vm->_dataIO->readUint16(imdPtr->handle);
+ }
+
+ if (cmd == 0xFFF1) {
+ retVal = 0x8000;
+ continue;
+ } else if (cmd == 0xFFF2) { // Skip (16 bit)
+ cmd = _vm->_dataIO->readUint16(imdPtr->handle);
+ _vm->_dataIO->seekData(imdPtr->handle, cmd, SEEK_CUR);
+ retVal = 0x8000;
+ continue;
+ } else if (cmd == 0xFFF3) { // Skip (32 bit)
+ cmd = _vm->_dataIO->readUint32(imdPtr->handle);
+ _vm->_dataIO->seekData(imdPtr->handle, cmd, SEEK_CUR);
+ retVal = 0x8000;
+ continue;
+ }
+ }
+
+ if (_soundStage != 0) {
+ char *soundBuf =
+ (char *) (_soundBuffer + _curSoundSlice * _soundSliceSize);
+
+ if (!hasNextCmd)
+ waitEndSoundSlice();
+
+ // Next sound slice data
+ if (cmd == 0xFF00) {
+
+ if (!hasNextCmd && !_noSound) {
+ _vm->_dataIO->readData(imdPtr->handle, soundBuf,
+ _soundSliceSize);
+ _vm->_snd->convToSigned((byte *) soundBuf, _soundSliceSize);
+ } else
+ _vm->_dataIO->seekData(imdPtr->handle,
+ _soundSliceSize, SEEK_CUR);
+
+ cmd = _vm->_dataIO->readUint16(imdPtr->handle);
+
+ // Initial sound data (all slices)
+ } else if (cmd == 0xFF01) {
+ int dataLength = _soundSliceSize * _soundSlicesCount;
+
+ if (!hasNextCmd && !_noSound) {
+ _vm->_dataIO->readData(imdPtr->handle,
+ (char *) _soundBuffer, dataLength);
+ _vm->_snd->convToSigned(_soundBuffer, dataLength);
+
+ _curSoundSlice = _soundSlicesCount - 1;
+ _soundStage = 1;
+ startSound = true;
+ } else
+ _vm->_dataIO->seekData(imdPtr->handle, dataLength, SEEK_CUR);
+
+ cmd = _vm->_dataIO->readUint16(imdPtr->handle);
+
+ // Clear sound slice
+ } else if (!hasNextCmd && (!_noSound))
+ memset(soundBuf, 0, _soundSliceSize);
+
+ if (!hasNextCmd)
+ _curSoundSlice = (_curSoundSlice + 1) % _soundSlicesCount;
+ }
+
+ // Set palette
+ if (cmd == 0xFFF4) {
+ _vm->_dataIO->seekData(imdPtr->handle, 2, SEEK_CUR);
+ retVal |= 0x10;
+ if (imdPtr->extraPalette) {
+ _vm->_dataIO->readData(imdPtr->handle,
+ (char *) imdPtr->extraPalette, 768);
+ _vm->_video->setPalette(imdPtr->extraPalette);
+ } else if (imdPtr->palette)
+ _vm->_dataIO->readData(imdPtr->handle,
+ (char *) imdPtr->palette, 768);
+ else
+ _vm->_dataIO->readData(imdPtr->handle,
+ (char *) _frameData, 768);
+
+ cmd = _vm->_dataIO->readUint16(imdPtr->handle);
+ }
+
+ hasNextCmd = false;
+
+ // Jump to frame
+ if (cmd == 0xFFFD) {
+
+ frame = _vm->_dataIO->readUint16(imdPtr->handle);
+ if (imdPtr->framesPos) {
+ imdPtr->curFrame = frame;
+ _vm->_dataIO->seekData(imdPtr->handle,
+ imdPtr->framesPos[frame], SEEK_SET);
+
+ hasNextCmd = true;
+ retVal |= 0x200;
+ }
+
+ } else if (cmd == 0xFFFC) {
+
+ retVal |= 1;
+ cmd = _vm->_dataIO->readUint32(imdPtr->handle);
+ _vm->_dataIO->readData(imdPtr->handle,
+ (char *) _frameData, cmd + 2);
+
+ if (imdPtr->surfDesc) {
+ int16 left = imdPtr->x;
+ int16 top = imdPtr->y;
+ int16 right = imdPtr->width + left;
+ int16 bottom = imdPtr->height + top;
+
+ if (imdPtr->surfDesc->getWidth() < right) {
+ left = 0;
+ right = imdPtr->width;
+ }
+ if (imdPtr->surfDesc->getWidth() < right)
+ right = imdPtr->surfDesc->getWidth();
+ if (imdPtr->surfDesc->getHeight() < bottom) {
+ top = 0;
+ bottom = imdPtr->height;
+ }
+ if (imdPtr->surfDesc->getHeight() < bottom)
+ bottom = imdPtr->surfDesc->getHeight();
+
+ imdPtr->x = left;
+ imdPtr->y = top;
+ imdPtr->height = bottom - top;
+ imdPtr->width = right - left;
+
+ renderFrame(imdPtr);
+ }
+
+ retVal |= _frameData[0];
+
+ // Frame video data
+ } else if (cmd != 0) {
+
+ _vm->_dataIO->readData(imdPtr->handle, (char *) _frameData, cmd + 2);
+ if (imdPtr->surfDesc)
+ renderFrame(imdPtr);
+
+ retVal |= _frameData[0];
+
+ } else
+ retVal |= 0x800;
+
+ } while (hasNextCmd);
+
+ if (startSound) {
+ _vm->_snd->stopSound(0);
+ _vm->_snd->playSample(_soundDesc, -1, _soundFreq);
+ _soundStage = 2;
+ }
+
+ imdPtr->x = xBak;
+ imdPtr->y = yBak;
+ imdPtr->width = widthBak;
+ imdPtr->height = heightBak;
+
+ imdPtr->curFrame++;
+ if ((imdPtr->curFrame == (imdPtr->framesCount - 1)) && (_soundStage == 2)) {
+ // Clear the remaining sound buffer
+ if (_curSoundSlice > 0)
+ memset(_soundBuffer + _curSoundSlice * _soundSliceSize, 0,
+ _soundSliceSize * _soundSlicesCount -
+ _curSoundSlice * _soundSliceSize);
+
+ _vm->_snd->setRepeating(0);
+ _vm->_snd->waitEndPlay();
+ }
+
+ return retVal;
+}
+
+inline void ImdPlayer::waitEndSoundSlice() {
+ _vm->_video->retrace();
+ _vm->_util->delay(_soundSliceLength);
}
} // End of namespace Gob
diff --git a/engines/gob/imd.h b/engines/gob/imd.h
index 162aa5676e..3069e9eb7d 100644
--- a/engines/gob/imd.h
+++ b/engines/gob/imd.h
@@ -25,6 +25,7 @@
#define GOB_IMD_H
#include "gob/video.h"
+#include "gob/sound.h"
namespace Gob {
@@ -41,7 +42,7 @@ public:
};
struct Imd {
- int16 fileHandle;
+ int16 handle;
int16 verMin;
int16 framesCount;
int16 x;
@@ -58,10 +59,10 @@ public:
int16 stdY;
int16 stdWidth;
int16 stdHeight;
- int32 filePos;
ImdCoord *frameCoords;
int32 frameDataSize;
int32 vidBufferSize;
+ Video::Color *extraPalette;
};
#include "common/pack-end.h" // END STRUCT PACKING
@@ -72,38 +73,65 @@ public:
byte *_frontMem;
int32 _frameDelay;
+ uint8 _soundStage; // (0: no sound, 1: loaded, 2: playing)
+
ImdPlayer(GobEngine *vm);
virtual ~ImdPlayer();
Imd *loadImdFile(const char *path, SurfaceDesc *surfDesc, int8 flags);
- void finishImd(Imd *imdPtr);
- int8 openImd(const char *path, int16 x, int16 y, int16 repeat, int16 flags);
+ void finishImd(Imd *&imdPtr);
+
+ int8 openImd(const char *path, int16 x, int16 y,
+ int16 startFrame, int16 flags);
void closeImd(void);
- void setXY(Imd *imdPtr, int16 x, int16 y);
- void play(int16 arg_0, uint16 palCmd, int16 palStart,
- int16 playEnd, int16 palFrame, int16 arg_A);
+ void play(int16 frame, uint16 palCmd, int16 palStart, int16 palEnd,
+ int16 palFrame, int16 lastFrame);
+ void play(const char *path, int16 x, int16 y, bool interruptible);
void play(const char *path, int16 x, int16 y, int16 startFrame,
int16 frames, bool fade, bool interruptible);
- int16 view(ImdPlayer::Imd *imdPtr, int16 arg_4);
- void drawFrame(Imd *imdPtr, int16 frame, int16 x, int16 y,
- SurfaceDesc *dest = 0);
- void renderframe(Imd *imdPtr);
- void frameUncompressor(byte *dest, byte *src);
- int16 sub_2C825(Imd *imdPtr);
protected:
char _curFile[15];
int16 _curX;
int16 _curY;
+ int16 _left;
+ int16 _top;
+ int16 _right;
+ int16 _bottom;
- uint16 _frameDataSize;
- uint16 _vidBufferSize;
byte *_frameData;
byte *_vidBuffer;
+ bool _noSound;
+ byte *_soundBuffer;
+
+ int16 _soundFreq;
+ uint16 _soundSliceSize;
+ int16 _soundSlicesCount;
+
+ uint16 _soundSliceLength;
+ uint16 _curSoundSlice;
+ SoundDesc _soundDesc;
+
GobEngine *_vm;
+
+ void copyPalette(int16 palStart, int16 palEnd);
+ void flipFrontMem();
+ void drawFrame(int16 frame);
+ void setXY(Imd *imdPtr, int16 x, int16 y);
+
+ void seekFrame(Imd *imdPtr, int16 frame, int16 from, bool restart = false);
+ uint16 checkFrameType(Imd *imdPtr, int16 frame);
+ void drawFrame(Imd *imdPtr, int16 frame, int16 x, int16 y,
+ SurfaceDesc *dest = 0);
+
+ uint32 view(ImdPlayer::Imd *imdPtr, int16 arg_4);
+ void renderFrame(Imd *imdPtr);
+ void frameUncompressor(byte *dest, byte *src);
+
+ void waitEndSoundSlice();
};
} // End of namespace Gob
diff --git a/engines/gob/init.cpp b/engines/gob/init.cpp
index 417fa7b52a..a3edb75d62 100644
--- a/engines/gob/init.cpp
+++ b/engines/gob/init.cpp
@@ -34,6 +34,7 @@
#include "gob/game.h"
#include "gob/sound.h"
#include "gob/video.h"
+#include "gob/imd.h"
namespace Gob {
@@ -55,6 +56,7 @@ void Init::cleanup(void) {
void Init::initGame(char *totName) {
int16 handle2;
int16 handle;
+ int16 imdHandle;
char *infBuf;
char *infPtr;
char *infEnd;
@@ -144,8 +146,7 @@ void Init::initGame(char *totName) {
if (handle >= 0) {
// Get variables count
_vm->_dataIO->seekData(handle, 0x2C, SEEK_SET);
- _vm->_dataIO->readData(handle, (char *) &varsCount, 2);
- varsCount = FROM_LE_16(varsCount);
+ varsCount = _vm->_dataIO->readUint16(handle);
_vm->_dataIO->closeData(handle);
_vm->_global->_inter_variables = new char[varsCount * 4];
@@ -157,6 +158,24 @@ void Init::initGame(char *totName) {
_vm->_cdrom->testCD(1, "GOB");
_vm->_cdrom->readLIC("gob.lic");
+
+ _vm->_draw->_cursorIndex = -1;
+ imdHandle = _vm->_dataIO->openData("coktel2.imd");
+ if (imdHandle >= 0) {
+ _vm->_dataIO->closeData(imdHandle);
+ _vm->_draw->initScreen();
+ _vm->_imdPlayer->play("coktel2", -1, -1, true);
+ _vm->_draw->closeScreen();
+ } else {
+ imdHandle = _vm->_dataIO->openData("coktel.imd");
+ if (imdHandle >= 0) {
+ _vm->_dataIO->closeData(imdHandle);
+ _vm->_draw->initScreen();
+ _vm->_imdPlayer->play("coktel", -1, -1, true);
+ _vm->_draw->closeScreen();
+ }
+ }
+
_vm->_game->start();
_vm->_cdrom->stopPlaying();
diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp
index f6081a8fb2..d5bc59fe19 100644
--- a/engines/gob/inter_v1.cpp
+++ b/engines/gob/inter_v1.cpp
@@ -2215,7 +2215,6 @@ bool Inter_v1::o1_readData(OpFuncParams &params) {
int16 dataVar;
int16 offset;
int16 handle;
- char buf[4];
evalExpr(0);
dataVar = _vm->_parse->parseVarIndex();
@@ -2230,14 +2229,13 @@ bool Inter_v1::o1_readData(OpFuncParams &params) {
if (handle >= 0) {
_vm->_draw->animateCursor(4);
if (offset < 0)
- _vm->_dataIO->seekData(handle, -offset - 1, 2);
+ _vm->_dataIO->seekData(handle, -offset - 1, SEEK_END);
else
- _vm->_dataIO->seekData(handle, offset, 0);
+ _vm->_dataIO->seekData(handle, offset, SEEK_SET);
- if (((dataVar >> 2) == 59) && (size == 4)) {
- retSize = _vm->_dataIO->readData(handle, buf, 4);
- WRITE_VAR(59, READ_LE_UINT32(buf));
- } else
+ if (((dataVar >> 2) == 59) && (size == 4))
+ WRITE_VAR(59, _vm->_dataIO->readUint32(handle));
+ else
retSize = _vm->_dataIO->readData(handle,
_vm->_global->_inter_variables + dataVar, size);
@@ -3009,7 +3007,7 @@ void Inter_v1::animPalette() {
if (_animPalDir[0] == 0)
return;
- _vm->_video->waitRetrace(_vm->_global->_videoMode);
+ _vm->_video->waitRetrace();
if (_animPalDir[0] == -1) {
col = _vm->_draw->_vgaSmallPalette[_animPalLowIndex[0]];
diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp
index 96fab8d675..74c129bac6 100644
--- a/engines/gob/inter_v2.cpp
+++ b/engines/gob/inter_v2.cpp
@@ -1472,24 +1472,36 @@ void Inter_v2::o2_playImd() {
palEnd = _vm->_parse->parseValExpr();
palCmd = 1 << (flags & 0x3F);
- if (!_vm->_imdPlayer->openImd(imd, x, y, startFrame, flags))
+ if (!_vm->_imdPlayer->openImd(imd, x, y, startFrame, flags)) {
+ WRITE_VAR(11, -1);
return;
+ }
close = (lastFrame == -1);
if (lastFrame < 0)
lastFrame = _vm->_imdPlayer->_curImd->framesCount - 1;
+ if (startFrame == -2) {
+ startFrame = lastFrame = 0;
+ close = false;
+ }
for (int i = startFrame; i <= lastFrame; i++) {
_vm->_imdPlayer->play(i, palCmd, palStart, palEnd, 0, lastFrame);
WRITE_VAR(11, i);
+ if (_vm->_quitRequested)
+ break;
+
if (breakKey != 0) {
_vm->_util->getMouseState(&_vm->_global->_inter_mouseX,
&_vm->_global->_inter_mouseY, &_vm->_game->_mouseButtons);
storeKey(_vm->_util->checkKey());
- if (VAR(0) == (unsigned) breakKey)
+ if (VAR(0) == (unsigned) breakKey) {
+ if (_vm->_imdPlayer->_soundStage == 2)
+ _vm->_snd->stopSound(0);
return;
+ }
}
}
@@ -1553,15 +1565,9 @@ void Inter_v2::o2_resetImdFrontSurf() {
_vm->_imdPlayer->_frontSurf = 21;
if (_vm->_imdPlayer->_frontMem) {
_vm->_imdPlayer->_frontMem = _vm->_draw->_frontSurface->getVidMem();
- _vm->_video->drawSprite(_vm->_draw->_backSurface,
- _vm->_draw->_frontSurface, 0, 0,
- _vm->_draw->_backSurface->getWidth() - 1,
- _vm->_draw->_backSurface->getHeight() - 1, 0, 0, 0);
+ _vm->_draw->forceBlit();
} else
- _vm->_video->drawSprite(_vm->_draw->_frontSurface,
- _vm->_draw->_backSurface, 0, 0,
- _vm->_draw->_backSurface->getWidth() - 1,
- _vm->_draw->_backSurface->getHeight() - 1, 0, 0, 0);
+ _vm->_draw->forceBlit(true);
}
bool Inter_v2::o2_evaluateStore(OpFuncParams &params) {
@@ -1811,7 +1817,6 @@ bool Inter_v2::o2_readData(OpFuncParams &params) {
int16 dataVar;
int16 handle;
char *buf;
- char tmp[4];
evalExpr(0);
dataVar = _vm->_parse->parseVarIndex();
@@ -1861,13 +1866,12 @@ bool Inter_v2::o2_readData(OpFuncParams &params) {
_vm->_draw->animateCursor(4);
if (offset < 0)
- _vm->_dataIO->seekData(handle, -offset - 1, 2);
+ _vm->_dataIO->seekData(handle, -offset - 1, SEEK_END);
else
- _vm->_dataIO->seekData(handle, offset, 0);
+ _vm->_dataIO->seekData(handle, offset, SEEK_SET);
if (((dataVar >> 2) == 59) && (size == 4)) {
- retSize = _vm->_dataIO->readData(handle, tmp, 4);
- WRITE_VAR(59, READ_LE_UINT32(tmp));
+ WRITE_VAR(59, _vm->_dataIO->readUint32(handle));
// The scripts in some versions divide through 256^3 then,
// effectively doing a LE->BE conversion
if ((_vm->_platform != Common::kPlatformPC) && (VAR(59) < 256))
@@ -2037,6 +2041,8 @@ int16 Inter_v2::loadSound(int16 search) {
source = SOUND_EXT;
dataPtr = (byte *) _vm->_game->loadExtData(id, 0, 0, &dataSize);
+ if (_vm->_game->_totFileData[0x29] >= 51)
+ _vm->_snd->convToSigned(dataPtr, dataSize);
} else {
int16 totSize;
@@ -2069,7 +2075,7 @@ void Inter_v2::animPalette() {
continue;
if (first) {
- _vm->_video->waitRetrace(_vm->_global->_videoMode);
+ _vm->_video->waitRetrace();
first = false;
}
diff --git a/engines/gob/mult.cpp b/engines/gob/mult.cpp
index 2cf94bd84a..73b2bbd843 100644
--- a/engines/gob/mult.cpp
+++ b/engines/gob/mult.cpp
@@ -336,7 +336,7 @@ void Mult::doPalAnim() {
}
if (_vm->_global->_colorCount == 256) {
- _vm->_video->waitRetrace(_vm->_global->_videoMode);
+ _vm->_video->waitRetrace();
palPtr = _vm->_global->_pPaletteDesc->vgaPal;
for (_counter = 0; _counter < 16; _counter++, palPtr++)
diff --git a/engines/gob/palanim.cpp b/engines/gob/palanim.cpp
index e2290c0244..98b6d0fa8d 100644
--- a/engines/gob/palanim.cpp
+++ b/engines/gob/palanim.cpp
@@ -176,7 +176,7 @@ void PalAnim::fade(Video::PalDesc *palDesc, int16 fadeV, int16 allColors) {
if (allColors == 0) {
do {
stop = fadeStep(0);
- _vm->_video->waitRetrace(_vm->_global->_videoMode);
+ _vm->_video->waitRetrace();
if (fadeV > 0)
_vm->_util->delay(fadeV);
@@ -190,17 +190,17 @@ void PalAnim::fade(Video::PalDesc *palDesc, int16 fadeV, int16 allColors) {
if (allColors == 1) {
do {
- _vm->_video->waitRetrace(_vm->_global->_videoMode);
+ _vm->_video->waitRetrace();
stop = fadeStep(1);
} while (!stop);
do {
- _vm->_video->waitRetrace(_vm->_global->_videoMode);
+ _vm->_video->waitRetrace();
stop = fadeStep(2);
} while (!stop);
do {
- _vm->_video->waitRetrace(_vm->_global->_videoMode);
+ _vm->_video->waitRetrace();
stop = fadeStep(3);
} while (!stop);
diff --git a/engines/gob/parse.h b/engines/gob/parse.h
index be7ae6c9ac..2fab96d7ad 100644
--- a/engines/gob/parse.h
+++ b/engines/gob/parse.h
@@ -59,7 +59,7 @@ public:
virtual ~Parse_v1() {};
virtual int16 parseVarIndex(void);
- virtual int16 parseValExpr(unsigned stopToken=99);
+ virtual int16 parseValExpr(unsigned stopToken = 99);
virtual int16 parseExpr(char stopToken, byte *resultPtr);
};
@@ -69,7 +69,7 @@ public:
virtual ~Parse_v2() {};
virtual int16 parseVarIndex(void);
- virtual int16 parseValExpr(unsigned stopToken=99);
+ virtual int16 parseValExpr(unsigned stopToken = 99);
virtual int16 parseExpr(char stopToken, byte *resultPtr);
};
diff --git a/engines/gob/sound.cpp b/engines/gob/sound.cpp
index 336f3b2c1c..fe5f7ede16 100644
--- a/engines/gob/sound.cpp
+++ b/engines/gob/sound.cpp
@@ -33,6 +33,17 @@
namespace Gob {
+void SoundDesc::set(SoundType type, SoundSource src,
+ byte *data, uint32 dSize) {
+
+ free();
+
+ _type = type;
+ _source = src;
+ _data = _dataPtr = data;
+ _size = dSize;
+}
+
void SoundDesc::load(SoundType type, SoundSource src,
byte *data, uint32 dSize) {
@@ -225,6 +236,12 @@ void Snd::stopSound(int16 fadeLength, SoundDesc *sndDesc) {
_curFadeSamples = 0;
}
+void Snd::setRepeating(int32 repCount) {
+ Common::StackLock slock(_mutex);
+
+ _repCount = repCount;
+}
+
void Snd::waitEndPlay(bool interruptible, bool stopComp) {
if (stopComp)
_compositionPos = -1;
diff --git a/engines/gob/sound.h b/engines/gob/sound.h
index 2981e222bd..93cb8081ed 100644
--- a/engines/gob/sound.h
+++ b/engines/gob/sound.h
@@ -54,6 +54,7 @@ public:
bool isId(int16 id) { return _dataPtr && _id == id; };
SoundType getType() { return _type; }
+ void set(SoundType type, SoundSource src, byte *data, uint32 dSize);
void load(SoundType type, SoundSource src, byte *data, uint32 dSize);
void free();
void flip();
@@ -104,8 +105,14 @@ public:
void playComposition(int16 *composition, int16 freqVal,
SoundDesc *sndDescs = 0, int8 sndCount = 60);
void stopComposition();
+ void setRepeating(int32 repCount);
void waitEndPlay(bool interruptible = false, bool stopComp = true);
+ static void convToSigned(byte *buffer, int length) {
+ while (length-- > 0)
+ *buffer++ ^= 0x80;
+ }
+
int readBuffer(int16 *buffer, const int numSamples);
bool isStereo() const { return false; }
bool endOfData() const { return _end; }
diff --git a/engines/gob/util.cpp b/engines/gob/util.cpp
index 1b0e01727d..d05a43f8fd 100644
--- a/engines/gob/util.cpp
+++ b/engines/gob/util.cpp
@@ -66,7 +66,7 @@ void Util::delay(uint16 msecs) {
void Util::longDelay(uint16 msecs) {
uint32 time = g_system->getMillis() + msecs;
do {
- _vm->_video->waitRetrace(_vm->_global->_videoMode);
+ _vm->_video->waitRetrace();
processInput();
delay(15);
} while (!_vm->_quitRequested && (g_system->getMillis() < time));
@@ -275,7 +275,7 @@ void Util::setFrameRate(int16 rate) {
void Util::waitEndFrame() {
int32 time;
- _vm->_video->waitRetrace(_vm->_global->_videoMode);
+ _vm->_video->waitRetrace();
time = getTimeKey() - _vm->_global->_startFrameTime;
if ((time > 1000) || (time < 0)) {
@@ -297,7 +297,7 @@ void Util::setScrollOffset(int16 x, int16 y) {
processInput();
_vm->_video->_scrollOffsetX = x >= 0 ? x : _vm->_draw->_scrollOffsetX;
_vm->_video->_scrollOffsetY = y >= 0 ? y : _vm->_draw->_scrollOffsetY;
- _vm->_video->waitRetrace(_vm->_global->_videoMode);
+ _vm->_video->waitRetrace();
}
Video::FontDesc *Util::loadFont(const char *path) {
diff --git a/engines/gob/video.cpp b/engines/gob/video.cpp
index 67798d81d8..4a9481a5fa 100644
--- a/engines/gob/video.cpp
+++ b/engines/gob/video.cpp
@@ -152,21 +152,25 @@ SurfaceDesc *Video::initSurfDesc(int16 vidMode, int16 width, int16 height,
return descPtr;
}
-void Video::waitRetrace(bool mouse) {
- uint32 time;
-
+void Video::retrace(bool mouse) {
if (mouse)
CursorMan.showMouse((_vm->_draw->_showCursor & 2) != 0);
if (_vm->_global->_primarySurfDesc) {
- time = _vm->_util->getTimeKey();
g_system->copyRectToScreen(_vm->_global->_primarySurfDesc->getVidMem() +
_scrollOffsetY * _surfWidth + _scrollOffsetX, _surfWidth,
0, 0, 320, 200);
g_system->updateScreen();
- _vm->_util->delay(MAX(1, 10 - (int)(_vm->_util->getTimeKey() - time)));
}
}
+void Video::waitRetrace(bool mouse) {
+ uint32 time;
+
+ time = _vm->_util->getTimeKey();
+ retrace(mouse);
+ _vm->_util->delay(MAX(1, 10 - (int)(_vm->_util->getTimeKey() - time)));
+}
+
void Video::putPixel(int16 x, int16 y, int16 color, SurfaceDesc *dest) {
if ((x >= dest->getWidth()) || (x < 0) ||
(y >= dest->getHeight()) || (y < 0))
@@ -403,4 +407,19 @@ void Video::setFullPalette(PalDesc *palDesc) {
Video::setPalette(palDesc);
}
+void Video::setPalette(Color *palette) {
+ Color *palBak;
+ bool setAllPalBak;
+
+ palBak = _vm->_global->_pPaletteDesc->vgaPal;
+ setAllPalBak = _vm->_global->_setAllPalette;
+
+ _vm->_global->_pPaletteDesc->vgaPal = palette;
+ _vm->_global->_setAllPalette = true;
+ setFullPalette(_vm->_global->_pPaletteDesc);
+
+ _vm->_global->_setAllPalette = setAllPalBak;
+ _vm->_global->_pPaletteDesc->vgaPal = palBak;
+}
+
} // End of namespace Gob
diff --git a/engines/gob/video.h b/engines/gob/video.h
index a896a1e2a0..50d74e80ec 100644
--- a/engines/gob/video.h
+++ b/engines/gob/video.h
@@ -104,6 +104,7 @@ public:
void initPrimary(int16 mode);
SurfaceDesc *initSurfDesc(int16 vidMode, int16 width,
int16 height, int16 flags);
+ void retrace(bool mouse = true);
void waitRetrace(bool mouse = true);
void putPixel(int16 x, int16 y, int16 color, SurfaceDesc *dest);
@@ -137,6 +138,7 @@ public:
int16 unused, int16 vidMode);
void setPalette(PalDesc *palDesc);
void setFullPalette(PalDesc *palDesc);
+ void setPalette(Color *palette);
virtual char spriteUncompressor(byte *sprBuf, int16 srcWidth,
int16 srcHeight, int16 x, int16 y, int16 transp,