From 623ca8802269914ab90a1127f89c66dd2cb571f1 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 29 Mar 2007 17:55:39 +0000 Subject: - Properly implemented the ImdPlayer - Some more clean-up svn-id: r26316 --- engines/gob/cdrom.cpp | 16 +- engines/gob/dataio.cpp | 58 +- engines/gob/dataio.h | 12 +- engines/gob/draw.cpp | 25 +- engines/gob/draw.h | 1 + engines/gob/draw_v1.cpp | 4 +- engines/gob/draw_v2.cpp | 4 +- engines/gob/game.cpp | 22 +- engines/gob/game_v2.cpp | 2 +- engines/gob/global.h | 4 - engines/gob/gob.cpp | 5 +- engines/gob/gob.h | 17 +- engines/gob/imd.cpp | 1342 +++++++++++++++++++++++++++------------------- engines/gob/imd.h | 58 +- engines/gob/init.cpp | 23 +- engines/gob/inter_v1.cpp | 14 +- engines/gob/inter_v2.cpp | 38 +- engines/gob/mult.cpp | 2 +- engines/gob/palanim.cpp | 8 +- engines/gob/parse.h | 4 +- engines/gob/sound.cpp | 17 + engines/gob/sound.h | 7 + engines/gob/util.cpp | 6 +- engines/gob/video.cpp | 29 +- engines/gob/video.h | 2 + 25 files changed, 1065 insertions(+), 655 deletions(-) (limited to 'engines') 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 ¶ms) { 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 ¶ms) { 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 ¶ms) { @@ -1811,7 +1817,6 @@ bool Inter_v2::o2_readData(OpFuncParams ¶ms) { 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 ¶ms) { _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, -- cgit v1.2.3