diff options
70 files changed, 10100 insertions, 11756 deletions
diff --git a/engines/gob/anim.cpp b/engines/gob/anim.cpp deleted file mode 100644 index a51befe3c8..0000000000 --- a/engines/gob/anim.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004 Ivan Dubrov - * Copyright (C) 2004-2006 The ScummVM project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ -#include "gob/gob.h" -#include "gob/video.h" -#include "gob/anim.h" - -namespace Gob { - -Anim::Anim() { - _areaLeft = 0; - _areaTop = 0; - _areaWidth = 0; - _areaHeight = 0; - _animSurf = 0; -} - -} // End of namespace Gob diff --git a/engines/gob/anim.h b/engines/gob/anim.h deleted file mode 100644 index f4d255e590..0000000000 --- a/engines/gob/anim.h +++ /dev/null @@ -1,43 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004 Ivan Dubrov - * Copyright (C) 2004-2006 The ScummVM project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ -#ifndef GOB_ANIM_H -#define GOB_ANIM_H - -#include "gob/video.h" - -namespace Gob { - -class Anim { -public: - int16 _areaLeft; - int16 _areaTop; - int16 _areaWidth; - int16 _areaHeight; - Video::SurfaceDesc *_animSurf; - - Anim(); -}; - -} // End of namespace Gob - -#endif diff --git a/engines/gob/cdrom.cpp b/engines/gob/cdrom.cpp index fcc7ba5dcd..a5c9fab90c 100644 --- a/engines/gob/cdrom.cpp +++ b/engines/gob/cdrom.cpp @@ -22,19 +22,20 @@ #include "common/stdafx.h" #include "common/endian.h" +#include "sound/audiocd.h" #include "gob/gob.h" #include "gob/cdrom.h" -#include "gob/dataio.h" -#include "gob/game.h" #include "gob/global.h" #include "gob/util.h" -#include "sound/audiocd.h" +#include "gob/dataio.h" +#include "gob/game.h" namespace Gob { CDROM::CDROM(GobEngine *vm) : _vm(vm) { _cdPlaying = false; + _LICbuffer = 0; for (int i = 0; i < 16; i++) _curTrack[i] = 0; @@ -54,50 +55,48 @@ void CDROM::readLIC(const char *fname) { strcpy(tmp, fname); - handle = _vm->_dataio->openData(tmp); + handle = _vm->_dataIO->openData(tmp); if (handle == -1) return; - _vm->_dataio->closeData(handle); + _vm->_dataIO->closeData(handle); - _vm->_dataio->getUnpackedData(tmp); + _vm->_dataIO->getUnpackedData(tmp); - handle = _vm->_dataio->openData(tmp); + handle = _vm->_dataIO->openData(tmp); - _vm->_dataio->readData(handle, (char *)&version, 2); + _vm->_dataIO->readData(handle, (char *)&version, 2); version = READ_LE_UINT16(&version); - _vm->_dataio->readData(handle, (char *)&startChunk, 2); + _vm->_dataIO->readData(handle, (char *)&startChunk, 2); startChunk = READ_LE_UINT16(&startChunk); - _vm->_dataio->readData(handle, (char *)&_numTracks, 2); + _vm->_dataIO->readData(handle, (char *)&_numTracks, 2); _numTracks = READ_LE_UINT16(&_numTracks); - if (version != 3) { - error("Wrong file %s (%d)", fname, version); - return; - } + if (version != 3) + error("%s: Unknown version %d", fname, version); - _vm->_dataio->seekData(handle, 50, SEEK_SET); + _vm->_dataIO->seekData(handle, 50, SEEK_SET); for (int i = 0; i < startChunk; i++) { - _vm->_dataio->readData(handle, (char *)&pos, 2); + _vm->_dataIO->readData(handle, (char *)&pos, 2); pos = READ_LE_UINT16(&pos); if (!pos) break; - _vm->_dataio->seekData(handle, pos, SEEK_CUR); + _vm->_dataIO->seekData(handle, pos, SEEK_CUR); } _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); + _vm->_dataIO->closeData(handle); } -void CDROM::freeLICbuffer(void) { +void CDROM::freeLICbuffer() { delete[] _LICbuffer; _LICbuffer = 0; } @@ -208,7 +207,7 @@ void CDROM::play(uint32 from, uint32 to) { _cdPlaying = true; } -int32 CDROM::getTrackPos(void) { +int32 CDROM::getTrackPos() { uint32 curPos = _vm->_util->getTimeKey() - _startTime; if (_cdPlaying && (_vm->_util->getTimeKey() < _trackStop)) @@ -217,17 +216,17 @@ int32 CDROM::getTrackPos(void) { return -1; } -const char *CDROM::getCurTrack(void) { +const char *CDROM::getCurTrack() { return _curTrack; } -void CDROM::stopPlaying(void) { +void CDROM::stopPlaying() { stop(); while (getTrackPos() != -1); } -void CDROM::stop(void) { +void CDROM::stop() { debugC(1, kDebugMusic, "CDROM::stop()"); AudioCD.stop(); diff --git a/engines/gob/cdrom.h b/engines/gob/cdrom.h index 6ea17e8a09..1120f3b11b 100644 --- a/engines/gob/cdrom.h +++ b/engines/gob/cdrom.h @@ -23,8 +23,6 @@ #ifndef GOB_CDROM_H #define GOB_CDROM_H -#include "gob/gob.h" - namespace Gob { class CDROM { @@ -32,16 +30,16 @@ public: bool _cdPlaying; void readLIC(const char *fname); - void freeLICbuffer(void); + void freeLICbuffer(); void startTrack(const char *s); void playBgMusic(); void playMultMusic(); void play(uint32 from, uint32 to); - int32 getTrackPos(void); - const char *getCurTrack(void); - void stopPlaying(void); - void stop(void); + int32 getTrackPos(); + const char *getCurTrack(); + void stopPlaying(); + void stop(); void testCD(int trySubst, const char *label); CDROM(GobEngine *vm); @@ -57,4 +55,4 @@ protected: } // End of namespace Gob -#endif +#endif // GOB_CDROM_H diff --git a/engines/gob/dataio.cpp b/engines/gob/dataio.cpp index f696bf6b62..7cb3b5c558 100644 --- a/engines/gob/dataio.cpp +++ b/engines/gob/dataio.cpp @@ -20,14 +20,87 @@ * $Id$ * */ + +#include "common/stdafx.h" +#include "common/endian.h" + #include "gob/gob.h" -#include "gob/global.h" #include "gob/dataio.h" -#include "gob/pack.h" +#include "gob/global.h" namespace Gob { DataIO::DataIO(GobEngine *vm) : _vm(vm) { + for (int i = 0; i < MAX_DATA_FILES; i++) { + _dataFiles[i] = 0; + _numDataChunks[i] = 0; + _dataFileHandles[i] = -1; + } + _packedSize = 0; +} + +int32 DataIO::unpackData(char *sourceBuf, char *destBuf) { + uint32 realSize; + uint32 counter; + uint16 cmd; + byte *src; + byte *dest; + byte *tmpBuf; + int16 off; + byte len; + uint16 tmpIndex; + + tmpBuf = new byte[4114]; + assert(tmpBuf); + + counter = realSize = READ_LE_UINT32(sourceBuf); + + for (int i = 0; i < 4078; i++) + tmpBuf[i] = 0x20; + tmpIndex = 4078; + + src = (byte *) (sourceBuf + 4); + dest = (byte *) destBuf; + + cmd = 0; + while (1) { + cmd >>= 1; + if ((cmd & 0x0100) == 0) { + cmd = *src | 0xFF00; + src++; + } + if ((cmd & 1) != 0) { /* copy */ + *dest++ = *src; + tmpBuf[tmpIndex] = *src; + src++; + tmpIndex++; + tmpIndex %= 4096; + counter--; + if (counter == 0) + break; + } else { /* copy string */ + + off = *src++; + off |= (*src & 0xF0) << 4; + len = (*src & 0x0F) + 3; + src++; + + for (int i = 0; i < len; i++) { + *dest++ = tmpBuf[(off + i) % 4096]; + counter--; + if (counter == 0) { + delete[] tmpBuf; + return realSize; + } + tmpBuf[tmpIndex] = tmpBuf[(off + i) % 4096]; + tmpIndex++; + tmpIndex %= 4096; + } + + } + } + delete[] tmpBuf; + return realSize; } Common::File *DataIO::file_getHandle(int16 handle) { @@ -53,34 +126,29 @@ int16 DataIO::file_open(const char *path, Common::File::AccessMode mode) { } int16 DataIO::getChunk(const char *chunkName) { - int16 file; int16 slot; - int16 chunk; struct ChunkDesc *dataDesc; - for (file = 0; file < MAX_DATA_FILES; file++) { - if (_vm->_global->_dataFiles[file] == 0) + for (int16 file = 0; file < MAX_DATA_FILES; file++) { + if (_dataFiles[file] == 0) return -1; for (slot = 0; slot < MAX_SLOT_COUNT; slot++) - if (_vm->_global->_chunkPos[file * MAX_SLOT_COUNT + slot] == -1) + if (_chunkPos[file * MAX_SLOT_COUNT + slot] == -1) break; if (slot == MAX_SLOT_COUNT) return -1; - dataDesc = _vm->_global->_dataFiles[file]; - for (chunk = 0; chunk < _vm->_global->_numDataChunks[file]; - chunk++, dataDesc++) { + dataDesc = _dataFiles[file]; + for (int16 chunk = 0; chunk < _numDataChunks[file]; chunk++, dataDesc++) { if (scumm_stricmp(chunkName, dataDesc->chunkName) != 0) continue; - _vm->_global->_isCurrentSlot[file * MAX_SLOT_COUNT + slot] = 0; - _vm->_global->_chunkSize[file * MAX_SLOT_COUNT + slot] = - dataDesc->size; - _vm->_global->_chunkOffset[file * MAX_SLOT_COUNT + slot] = - dataDesc->offset; - _vm->_global->_chunkPos[file * MAX_SLOT_COUNT + slot] = 0; + _isCurrentSlot[file * MAX_SLOT_COUNT + slot] = false; + _chunkSize[file * MAX_SLOT_COUNT + slot] = dataDesc->size; + _chunkOffset[file * MAX_SLOT_COUNT + slot] = dataDesc->offset; + _chunkPos[file * MAX_SLOT_COUNT + slot] = 0; return file * 10 + slot + 50; } } @@ -88,45 +156,47 @@ int16 DataIO::getChunk(const char *chunkName) { } char DataIO::freeChunk(int16 handle) { - if (handle >= 50 && handle < 100) { + if ((handle >= 50) && (handle < 100)) { handle -= 50; - _vm->_global->_chunkPos[(handle / 10) * MAX_SLOT_COUNT + (handle % 10)] = -1; + _chunkPos[(handle / 10) * MAX_SLOT_COUNT + (handle % 10)] = -1; return 0; } return 1; } -int32 DataIO::readChunk(int16 handle, char *buf, int16 size) { +int32 DataIO::readChunk(int16 handle, char *buf, uint16 size) { int16 file; int16 slot; int16 i; int32 offset; - if (handle < 50 || handle >= 100) + if ((handle < 50) || (handle >= 100)) return -2; file = (handle - 50) / 10; slot = (handle - 50) % 10; - if (_vm->_global->_isCurrentSlot[file * MAX_SLOT_COUNT + slot] == 0) { + if (!_isCurrentSlot[file * MAX_SLOT_COUNT + slot]) { for (i = 0; i < MAX_SLOT_COUNT; i++) - _vm->_global->_isCurrentSlot[file * MAX_SLOT_COUNT + i] = 0; + _isCurrentSlot[file * MAX_SLOT_COUNT + i] = false; + + offset = _chunkOffset[file * MAX_SLOT_COUNT + slot] + + _chunkPos[file * MAX_SLOT_COUNT + slot]; - offset = - _vm->_global->_chunkOffset[file * MAX_SLOT_COUNT + slot] + - _vm->_global->_chunkPos[file * MAX_SLOT_COUNT + slot]; - debugC(7, kDebugFileIO, "seek: %d, %d", _vm->_global->_chunkOffset[file * MAX_SLOT_COUNT + slot], _vm->_global->_chunkPos[file * MAX_SLOT_COUNT + slot]); - file_getHandle(_vm->_global->_dataFileHandles[file])->seek(offset, SEEK_SET); + debugC(7, kDebugFileIO, "seek: %d, %d", + _chunkOffset[file * MAX_SLOT_COUNT + slot], + _chunkPos[file * MAX_SLOT_COUNT + slot]); + + file_getHandle(_dataFileHandles[file])->seek(offset, SEEK_SET); } - _vm->_global->_isCurrentSlot[file * MAX_SLOT_COUNT + slot] = 1; - if (_vm->_global->_chunkPos[file * MAX_SLOT_COUNT + slot] + size > - _vm->_global->_chunkSize[file * MAX_SLOT_COUNT + slot]) - size = - _vm->_global->_chunkSize[file * MAX_SLOT_COUNT + slot] - - _vm->_global->_chunkPos[file * MAX_SLOT_COUNT + slot]; + _isCurrentSlot[file * MAX_SLOT_COUNT + slot] = true; + if ((_chunkPos[file * MAX_SLOT_COUNT + slot] + size) > + (_chunkSize[file * MAX_SLOT_COUNT + slot])) + size = _chunkSize[file * MAX_SLOT_COUNT + slot] - + _chunkPos[file * MAX_SLOT_COUNT + slot]; - file_getHandle(_vm->_global->_dataFileHandles[file])->read(buf, size); - _vm->_global->_chunkPos[file * MAX_SLOT_COUNT + slot] += size; + file_getHandle(_dataFileHandles[file])->read(buf, size); + _chunkPos[file * MAX_SLOT_COUNT + slot] += size; return size; } @@ -134,18 +204,18 @@ int16 DataIO::seekChunk(int16 handle, int32 pos, int16 from) { int16 file; int16 slot; - if (handle < 50 || handle >= 100) + if ((handle < 50) || (handle >= 100)) return -1; file = (handle - 50) / 10; slot = (handle - 50) % 10; - _vm->_global->_isCurrentSlot[file * MAX_SLOT_COUNT + slot] = 0; + _isCurrentSlot[file * MAX_SLOT_COUNT + slot] = false; if (from == SEEK_SET) - _vm->_global->_chunkPos[file * MAX_SLOT_COUNT + slot] = pos; + _chunkPos[file * MAX_SLOT_COUNT + slot] = pos; else - _vm->_global->_chunkPos[file * MAX_SLOT_COUNT + slot] += pos; + _chunkPos[file * MAX_SLOT_COUNT + slot] += pos; - return _vm->_global->_chunkPos[file * MAX_SLOT_COUNT + slot]; + return _chunkPos[file * MAX_SLOT_COUNT + slot]; } int32 DataIO::getChunkSize(const char *chunkName) { @@ -156,83 +226,80 @@ int32 DataIO::getChunkSize(const char *chunkName) { int32 realSize; for (file = 0; file < MAX_DATA_FILES; file++) { - if (_vm->_global->_dataFiles[file] == 0) + if (_dataFiles[file] == 0) return -1; - dataDesc = _vm->_global->_dataFiles[file]; - for (chunk = 0; chunk < _vm->_global->_numDataChunks[file]; - chunk++, dataDesc++) { + dataDesc = _dataFiles[file]; + for (chunk = 0; chunk < _numDataChunks[file]; chunk++, dataDesc++) { if (scumm_stricmp(chunkName, dataDesc->chunkName) != 0) continue; if (dataDesc->packed == 0) { - _vm->_global->_packedSize = -1; + _packedSize = -1; return dataDesc->size; } for (slot = 0; slot < MAX_SLOT_COUNT; slot++) - _vm->_global->_isCurrentSlot[slot] = 0; + _isCurrentSlot[slot] = false; - file_getHandle(_vm->_global->_dataFileHandles[file])->seek(dataDesc->offset, SEEK_SET); - realSize = file_getHandle(_vm->_global->_dataFileHandles[file])->readUint32LE(); - _vm->_global->_packedSize = dataDesc->size; + file_getHandle(_dataFileHandles[file])->seek(dataDesc->offset, SEEK_SET); + realSize = file_getHandle(_dataFileHandles[file])->readUint32LE(); + _packedSize = dataDesc->size; return realSize; } } return -1; } -void DataIO::openDataFile(const char *src) { +void DataIO::openDataFile(const char *src, bool itk) { + ChunkDesc *dataDesc; char path[128]; - int16 i; int16 file; - ChunkDesc *dataDesc; strcpy(path, src); - for (i = 0; path[i] != '.' && path[i] != 0; i++); - if (path[i] == 0) + if (!strchr(path, '.')) strcat(path, ".stk"); for (file = 0; file < MAX_DATA_FILES; file++) - if (_vm->_global->_dataFiles[file] == 0) + if (_dataFiles[file] == 0) break; if (file == MAX_DATA_FILES) - error("dataFileOpen: Data file slots are full\n"); - _vm->_global->_dataFileHandles[file] = file_open(path); + error("openDataFile: Data file slots are full"); - if (_vm->_global->_dataFileHandles[file] == -1) - error("dataFileOpen: Can't open %s data file\n", path); + _dataFileHandles[file] = file_open(path); - _vm->_global->_numDataChunks[file] = file_getHandle(_vm->_global->_dataFileHandles[file])->readUint16LE(); + if (_dataFileHandles[file] == -1) + error("openDataFile: Can't open %s data file", path); - debugC(7, kDebugFileIO, "DataChunks: %d [for %s]", _vm->_global->_numDataChunks[file], path); + _dataFileItk[file] = itk; + _numDataChunks[file] = file_getHandle(_dataFileHandles[file])->readUint16LE(); - dataDesc = new ChunkDesc[_vm->_global->_numDataChunks[file]]; - _vm->_global->_dataFiles[file] = dataDesc; + debugC(7, kDebugFileIO, "DataChunks: %d [for %s]", _numDataChunks[file], path); - for (i = 0; i < _vm->_global->_numDataChunks[file]; i++) { - file_getHandle(_vm->_global->_dataFileHandles[file])->read(dataDesc[i].chunkName, 13); - dataDesc[i].size = file_getHandle(_vm->_global->_dataFileHandles[file])->readUint32LE(); - dataDesc[i].offset = file_getHandle(_vm->_global->_dataFileHandles[file])->readUint32LE(); - dataDesc[i].packed = file_getHandle(_vm->_global->_dataFileHandles[file])->readByte(); + dataDesc = new ChunkDesc[_numDataChunks[file]]; + _dataFiles[file] = dataDesc; + + for (int i = 0; i < _numDataChunks[file]; i++) { + file_getHandle(_dataFileHandles[file])->read(dataDesc[i].chunkName, 13); + dataDesc[i].size = file_getHandle(_dataFileHandles[file])->readUint32LE(); + dataDesc[i].offset = file_getHandle(_dataFileHandles[file])->readUint32LE(); + dataDesc[i].packed = file_getHandle(_dataFileHandles[file])->readByte(); } - for (i = 0; i < _vm->_global->_numDataChunks[file]; i++) + for (int i = 0; i < _numDataChunks[file]; i++) debugC(7, kDebugFileIO, "%d: %s %d", i, dataDesc[i].chunkName, dataDesc[i].size); - for (i = 0; i < MAX_SLOT_COUNT; i++) - _vm->_global->_chunkPos[file * MAX_SLOT_COUNT + i] = -1; - + for (int i = 0; i < MAX_SLOT_COUNT; i++) + _chunkPos[file * MAX_SLOT_COUNT + i] = -1; } -void DataIO::closeDataFile() { - int16 file; - for (file = MAX_DATA_FILES - 1; file >= 0; file--) { - if (_vm->_global->_dataFiles[file] != 0) { - delete[] _vm->_global->_dataFiles[file]; - _vm->_global->_dataFiles[file] = 0; - file_getHandle(_vm->_global->_dataFileHandles[file])->close(); +void DataIO::closeDataFile(bool itk) { + for (int file = MAX_DATA_FILES - 1; file >= 0; file--) { + if (_dataFiles[file] && (_dataFileItk[file] == itk)) { + delete[] _dataFiles[file]; + _dataFiles[file] = 0; + file_getHandle(_dataFileHandles[file])->close(); return; } } @@ -247,7 +314,7 @@ char *DataIO::getUnpackedData(const char *name) { int32 sizeLeft; realSize = getChunkSize(name); - if (_vm->_global->_packedSize == -1 || realSize == -1) + if ((_packedSize == -1) || (realSize == -1)) return 0; chunk = getChunk(name); @@ -255,16 +322,12 @@ char *DataIO::getUnpackedData(const char *name) { return 0; unpackBuf = new char[realSize]; - if (unpackBuf == 0) - return 0; + assert(unpackBuf); - packBuf = new char[_vm->_global->_packedSize]; - if (packBuf == 0) { - delete[] unpackBuf; - return 0; - } + packBuf = new char[_packedSize]; + assert(packBuf); - sizeLeft = _vm->_global->_packedSize; + sizeLeft = _packedSize; ptr = packBuf; while (sizeLeft > 0x4000) { readChunk(chunk, ptr, 0x4000); @@ -273,7 +336,7 @@ char *DataIO::getUnpackedData(const char *name) { } readChunk(chunk, ptr, sizeLeft); freeChunk(chunk); - _vm->_pack->unpackData(packBuf, unpackBuf); + unpackData(packBuf, unpackBuf); delete[] packBuf; return unpackBuf; @@ -297,7 +360,7 @@ int16 DataIO::openData(const char *path, Common::File::AccessMode mode) { return file_open(path, mode); } -int32 DataIO::readData(int16 handle, char *buf, int16 size) { +int32 DataIO::readData(int16 handle, char *buf, uint16 size) { int32 res; res = readChunk(handle, buf, size); @@ -307,6 +370,10 @@ int32 DataIO::readData(int16 handle, char *buf, int16 size) { return file_getHandle(handle)->read(buf, size); } +int32 DataIO::writeData(int16 handle, char *buf, uint16 size) { + return file_getHandle(handle)->write(buf, size); +} + void DataIO::seekData(int16 handle, int32 pos, int16 from) { int32 resPos; @@ -347,13 +414,12 @@ char *DataIO::getData(const char *path) { int16 handle; data = getUnpackedData(path); - if (data != 0) + if (data) return data; size = getDataSize(path); data = new char[size]; - if (data == 0) - return 0; + assert(data); handle = openData(path); @@ -368,4 +434,4 @@ char *DataIO::getData(const char *path) { return data; } -} // End of namespace Gob +} // End of namespace Gob diff --git a/engines/gob/dataio.h b/engines/gob/dataio.h index cf6b5347a3..2fb90f15d5 100644 --- a/engines/gob/dataio.h +++ b/engines/gob/dataio.h @@ -20,11 +20,11 @@ * $Id$ * */ + #ifndef GOB_DATAIO_H #define GOB_DATAIO_H #include "common/file.h" -#include "gob/gob.h" namespace Gob { @@ -41,31 +41,47 @@ public: ChunkDesc() : size(0), offset(0), packed(0) { chunkName[0] = 0; } }; - int16 file_open(const char *path, Common::File::AccessMode mode = Common::File::kFileReadMode); - Common::File *file_getHandle(int16 handle); - int16 getChunk(const char *chunkName); - char freeChunk(int16 handle); - int32 readChunk(int16 handle, char *buf, int16 size); - int16 seekChunk(int16 handle, int32 pos, int16 from); - int32 getChunkSize(const char *chunkName); - void openDataFile(const char *src); - void closeDataFile(void); + int32 unpackData(char *source, char *dest); + + void openDataFile(const char *src, bool itk = 0); + void closeDataFile(bool itk = 0); char *getUnpackedData(const char *name); void closeData(int16 handle); - int16 openData(const char *path, Common::File::AccessMode mode = Common::File::kFileReadMode); - int32 readData(int16 handle, char *buf, int16 size); + int16 openData(const char *path, + Common::File::AccessMode mode = Common::File::kFileReadMode); + int32 readData(int16 handle, char *buf, uint16 size); + int32 writeData(int16 handle, char *buf, uint16 size); void seekData(int16 handle, int32 pos, int16 from); int32 getPos(int16 handle); int32 getDataSize(const char *name); char *getData(const char *path); - char *getSmallData(const char *path); DataIO(class GobEngine *vm); protected: + struct ChunkDesc *_dataFiles[MAX_DATA_FILES]; + int16 _numDataChunks[MAX_DATA_FILES]; + int16 _dataFileHandles[MAX_DATA_FILES]; + bool _dataFileItk[MAX_DATA_FILES]; + int32 _chunkPos[MAX_SLOT_COUNT * MAX_DATA_FILES]; + int32 _chunkOffset[MAX_SLOT_COUNT * MAX_DATA_FILES]; + int32 _chunkSize[MAX_SLOT_COUNT * MAX_DATA_FILES]; + bool _isCurrentSlot[MAX_SLOT_COUNT * MAX_DATA_FILES]; + int32 _packedSize; + class GobEngine *_vm; + + int16 file_open(const char *path, + Common::File::AccessMode mode = Common::File::kFileReadMode); + Common::File *file_getHandle(int16 handle); + + int16 getChunk(const char *chunkName); + char freeChunk(int16 handle); + int32 readChunk(int16 handle, char *buf, uint16 size); + int16 seekChunk(int16 handle, int32 pos, int16 from); + int32 getChunkSize(const char *chunkName); }; -} // End of namespace Gob +} // End of namespace Gob -#endif +#endif // GOB_DATAIO_H diff --git a/engines/gob/detection.cpp b/engines/gob/detection.cpp index 5ff2cf664a..55733b9be5 100644 --- a/engines/gob/detection.cpp +++ b/engines/gob/detection.cpp @@ -21,9 +21,7 @@ */ #include "common/stdafx.h" - #include "base/plugins.h" - #include "common/advancedDetector.h" #include "gob/gob.h" diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp index 2d84800360..759b15bc37 100644 --- a/engines/gob/draw.cpp +++ b/engines/gob/draw.cpp @@ -27,19 +27,15 @@ #include "gob/gob.h" #include "gob/draw.h" #include "gob/global.h" -#include "gob/video.h" -#include "gob/game.h" #include "gob/util.h" -#include "gob/scenery.h" +#include "gob/game.h" #include "gob/inter.h" #include "gob/video.h" -#include "gob/palanim.h" -#include "gob/cdrom.h" namespace Gob { Draw::Draw(GobEngine *vm) : _vm(vm) { - int i; + _renderFlags = 0; _fontIndex = 0; _spriteLeft = 0; @@ -50,74 +46,78 @@ Draw::Draw(GobEngine *vm) : _vm(vm) { _destSpriteY = 0; _backColor = 0; _frontColor = 0; - _letterToPrint = 0; + _transparency = 0; - _destSurface = 0; _sourceSurface = 0; - _renderFlags = 0; + _destSurface = 0; + + _letterToPrint = 0; + _textToPrint = 0; + _backDeltaX = 0; _backDeltaY = 0; - for (i = 0; i < 8; i++) + for (int i = 0; i < 8; i++) _fonts[i] = 0; - _textToPrint = 0; - _transparency = 0; - - for (i = 0; i < 50; i++) + for (int i = 0; i < SPRITES_COUNT; i++) _spritesArray[i] = 0; _invalidatedCount = 0; - for (i = 0; i < 30; i++) { + for (int i = 0; i < 30; i++) { _invalidatedTops[i] = 0; _invalidatedLefts[i] = 0; _invalidatedRights[i] = 0; _invalidatedBottoms[i] = 0; } - _noInvalidated = 0; - _applyPal = 0; - _paletteCleared = 0; + _noInvalidated = false; + _noInvalidated57 = false; + _paletteCleared = false; + _applyPal = false; _backSurface = 0; _frontSurface = 0; - for (i = 0; i < 18; i++) + for (int i = 0; i < 18; i++) _unusedPalette1[i] = 0; - for (i = 0; i < 16; i++) + for (int i = 0; i < 16; i++) _unusedPalette2[i] = 0; - for (i = 0; i < 256; i++) { + for (int i = 0; i < 256; i++) { _vgaPalette[i].red = 0; _vgaPalette[i].blue = 0; _vgaPalette[i].green = 0; } - for (i = 0; i < 16; i++) { + for (int i = 0; i < 16; i++) { _vgaSmallPalette[i].red = 0; _vgaSmallPalette[i].blue = 0; _vgaSmallPalette[i].green = 0; } + _showCursor = 0; + _cursorIndex = 0; + _transparentCursor = 0; + _cursorTimeKey = 0; + _cursorX = 0; _cursorY = 0; _cursorWidth = 0; _cursorHeight = 0; - _cursorXDeltaVar = -1; - _cursorYDeltaVar = -1; + _cursorHotspotXVar = -1; + _cursorHotspotYVar = -1; + + _cursorSprites = 0; + _cursorSpritesBack = 0; + _scummvmCursor = 0; - for (i = 0; i < 40; i++) { + _cursorAnim = 0; + for (int i = 0; i < 40; i++) { _cursorAnimLow[i] = 0; _cursorAnimHigh[i] = 0; _cursorAnimDelays[i] = 0; } - _showCursor = 0; - _cursorIndex = 0; - _transparentCursor = 0; - _cursorSprites = 0; - _scummvmCursor = 0; - _cursorAnim = 0; - _palLoadData1[0] = 0; _palLoadData1[1] = 17; _palLoadData1[2] = 34; @@ -127,42 +127,25 @@ Draw::Draw(GobEngine *vm) : _vm(vm) { _palLoadData2[2] = 136; _palLoadData2[3] = 204; - _cursorTimeKey = 0; - + _needAdjust = 2; _scrollOffsetX = 0; _scrollOffsetY = 0; - - warning("GOB2 Stub! _word_2E8E2, _word_2E51F, _off_2E51B, _off_2E517"); - _word_2E8E2 = 2; - _word_2E51F = 0; - _off_2E51B = 0; - _off_2E517 = 0; } void Draw::invalidateRect(int16 left, int16 top, int16 right, int16 bottom) { - int16 temp; - int16 rect; - int16 i; - if (_renderFlags & RENDERFLAG_NOINVALIDATE) return; - if (left > right) { - temp = left; - left = right; - right = temp; - } - if (top > bottom) { - temp = top; - top = bottom; - bottom = temp; - } + if (left > right) + SWAP(left, right); + if (top > bottom) + SWAP(top, bottom); if ((left > (_vm->_video->_surfWidth - 1)) || (right < 0) || - (top > (_vm->_video->_surfHeight - 1)) || (bottom < 0)) + (top > (_vm->_video->_surfHeight - 1)) || (bottom < 0)) return; - _noInvalidated = 0; + _noInvalidated = false; if (_invalidatedCount >= 30) { _invalidatedLefts[0] = 0; @@ -185,22 +168,18 @@ void Draw::invalidateRect(int16 left, int16 top, int16 right, int16 bottom) { if (bottom > (_vm->_video->_surfHeight - 1)) bottom = _vm->_video->_surfHeight - 1; - left &= 0xfff0; - right |= 0x000f; + left &= 0xFFF0; + right |= 0x000F; - for (rect = 0; rect < _invalidatedCount; rect++) { + for (int rect = 0; rect < _invalidatedCount; rect++) { if (_invalidatedTops[rect] > top) { if (_invalidatedTops[rect] > bottom) { - for (i = _invalidatedCount; i > rect; i--) { - _invalidatedLefts[i] = - _invalidatedLefts[i - 1]; - _invalidatedTops[i] = - _invalidatedTops[i - 1]; - _invalidatedRights[i] = - _invalidatedRights[i - 1]; - _invalidatedBottoms[i] = - _invalidatedBottoms[i - 1]; + for (int i = _invalidatedCount; i > rect; i--) { + _invalidatedLefts[i] = _invalidatedLefts[i - 1]; + _invalidatedTops[i] = _invalidatedTops[i - 1]; + _invalidatedRights[i] = _invalidatedRights[i - 1]; + _invalidatedBottoms[i] = _invalidatedBottoms[i - 1]; } _invalidatedLefts[rect] = left; _invalidatedTops[rect] = top; @@ -242,12 +221,12 @@ void Draw::invalidateRect(int16 left, int16 top, int16 right, int16 bottom) { _invalidatedRights[_invalidatedCount] = right; _invalidatedBottoms[_invalidatedCount] = bottom; _invalidatedCount++; - return; } -void Draw::blitInvalidated(void) { - int16 i; - +void Draw::blitInvalidated() { + if (_noInvalidated57 && + ((_vm->_global->_videoMode == 5) || (_vm->_global->_videoMode == 7))) + return; if (_cursorIndex == 4) blitCursor(); @@ -255,12 +234,12 @@ void Draw::blitInvalidated(void) { if (_vm->_inter->_terminate) return; - if (_noInvalidated && _applyPal == 0) + if (_noInvalidated && !_applyPal) return; if (_noInvalidated) { setPalette(); - _applyPal = 0; + _applyPal = false; return; } @@ -268,86 +247,89 @@ void Draw::blitInvalidated(void) { if (_applyPal) { clearPalette(); - _vm->_video->drawSprite(_backSurface, _frontSurface, 0, 0, - _vm->_video->_surfWidth - 1, _vm->_video->_surfHeight - 1, 0, 0, 0); + _vm->_video->drawSprite(_backSurface, _frontSurface, + 0, 0, _vm->_video->_surfWidth - 1, + _vm->_video->_surfHeight - 1, 0, 0, 0); setPalette(); _invalidatedCount = 0; - _noInvalidated = 1; - _applyPal = 0; + _noInvalidated = true; + _applyPal = false; return; } - _vm->_global->_doRangeClamp = 0; - for (i = 0; i < _invalidatedCount; i++) { + _vm->_video->_doRangeClamp = false; + for (int i = 0; i < _invalidatedCount; i++) { _vm->_video->drawSprite(_backSurface, _frontSurface, _invalidatedLefts[i], _invalidatedTops[i], _invalidatedRights[i], _invalidatedBottoms[i], _invalidatedLefts[i], _invalidatedTops[i], 0); } - _vm->_global->_doRangeClamp = 1; + _vm->_video->_doRangeClamp = true; _invalidatedCount = 0; - _noInvalidated = 1; - _applyPal = 0; + _noInvalidated = true; + _applyPal = false; } -void Draw::setPalette(void) { - if ((_vm->_global->_videoMode != 0x13) && (_vm->_global->_videoMode != 0x14)) - error("setPalette: Video mode 0x%x is not supported!\n", - _vm->_global->_videoMode); +void Draw::setPalette() { + _vm->validateVideoMode(_vm->_global->_videoMode); _vm->_global->_pPaletteDesc->unused1 = _unusedPalette1; _vm->_global->_pPaletteDesc->unused2 = _unusedPalette2; _vm->_global->_pPaletteDesc->vgaPal = _vgaPalette; _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); - _paletteCleared = 0; + _paletteCleared = false; } -void Draw::clearPalette(void) { - if (_paletteCleared == 0) { - _paletteCleared = 1; +void Draw::clearPalette() { + if (!_paletteCleared) { _vm->_util->clearPalette(); + _paletteCleared = true; } } -void Draw::freeSprite(int16 index) { - if (_spritesArray[index] == 0) - return; - - _vm->_video->freeSurfDesc(_spritesArray[index]); +void Draw::initSpriteSurf(int16 index, int16 width, int16 height, + int16 flags) { - _spritesArray[index] = 0; + _spritesArray[index] = + _vm->_video->initSurfDesc(_vm->_global->_videoMode, width, height, flags); + _vm->_video->clearSurf(_spritesArray[index]); } void Draw::adjustCoords(char adjust, int16 *coord1, int16 *coord2) { - if (_word_2E8E2 == 2) + if (_needAdjust == 2) return; - if (adjust == 0) { - if (coord2 != 0) - *coord2 *= 2; - if (coord1 != 0) - *coord2 *= 2; - } - else if (adjust == 1) { - if (coord2 != 0) - *coord2 = (signed) ((unsigned) (*coord2 + 1) / 2); - if (coord1 != 0) - *coord1 = (signed) ((unsigned) (*coord1 + 1) / 2); - } - else if (adjust == 2) { - if (coord2 != 0) - *coord2 = *coord2 * 2 + 1; - if (coord1 != 0) - *coord1 = *coord1 * 2 + 1; + switch (adjust) { + case 0: + if (coord2) + *coord2 *= 2; + if (coord1) + *coord2 *= 2; + break; + + case 1: + if (coord2) + *coord2 = (signed) ((unsigned) (*coord2 + 1) / 2); + if (coord1) + *coord1 = (signed) ((unsigned) (*coord1 + 1) / 2); + break; + + case 2: + if (coord2) + *coord2 = *coord2 * 2 + 1; + if (coord1) + *coord1 = *coord1 * 2 + 1; + break; } } void Draw::drawString(char *str, int16 x, int16 y, int16 color1, int16 color2, - int16 transp, Video::SurfaceDesc *dest, Video::FontDesc *font) { + int16 transp, SurfaceDesc *dest, Video::FontDesc *font) { + while (*str != '\0') { _vm->_video->drawLetter(*str, x, y, font, transp, color1, color2, dest); - if (font->extraData == 0) + if (!font->extraData) x += font->itemWidth; else x += *(((char *)font->extraData) + (*str - font->startItem)); @@ -355,25 +337,21 @@ void Draw::drawString(char *str, int16 x, int16 y, int16 color1, int16 color2, } } -void Draw::printTextCentered(int16 arg_0, int16 left, int16 top, int16 right, +void Draw::printTextCentered(int16 id, int16 left, int16 top, int16 right, int16 bottom, char *str, int16 fontIndex, int16 color) { - char *storedIP; - int i; - int length; - int16 width; - + adjustCoords(1, &left, &top); adjustCoords(1, &right, &bottom); if (READ_LE_UINT16(_vm->_game->_totFileData + 0x7E) != 0) { - storedIP = _vm->_global->_inter_execPtr; + char *storedIP = _vm->_global->_inter_execPtr; _vm->_global->_inter_execPtr = _vm->_game->_totFileData + READ_LE_UINT16(_vm->_game->_totFileData + 0x7E); - WRITE_VAR(17, (uint32) arg_0); + WRITE_VAR(17, (uint32) id); WRITE_VAR(18, (uint32) left); WRITE_VAR(19, (uint32) top); - WRITE_VAR(20, (uint32) right-left+1); - WRITE_VAR(21, (uint32) bottom-top+1); + WRITE_VAR(20, (uint32) (right - left + 1)); + WRITE_VAR(21, (uint32) (bottom - top + 1)); _vm->_inter->funcBlock(0); _vm->_global->_inter_execPtr = storedIP; } @@ -381,21 +359,23 @@ void Draw::printTextCentered(int16 arg_0, int16 left, int16 top, int16 right, if (str[0] == '\0') return; + int16 width = 0; + _transparency = 1; _destSpriteX = left; _destSpriteY = top; _fontIndex = fontIndex; _frontColor = color; _textToPrint = str; - width = 0; - if (_fonts[fontIndex]->extraData == 0) - width = strlen(str) * _fonts[fontIndex]->itemWidth; - else { - length = strlen(str); - for (i = 0; i < length; i++) - width += - *(((char*)_fonts[fontIndex]->extraData) + (str[i] - _fonts[_fontIndex]->startItem)); + if (_fonts[fontIndex]->extraData != 0) { + char *data = (char *) _fonts[fontIndex]->extraData; + int length = strlen(str); + + for (int i = 0; i < length; i++) + width += *(data + (str[i] - _fonts[_fontIndex]->startItem)); } + else + width = strlen(str) * _fonts[fontIndex]->itemWidth; adjustCoords(1, &width, 0); _destSpriteX += (right - left + 1 - width) / 2; @@ -404,19 +384,10 @@ void Draw::printTextCentered(int16 arg_0, int16 left, int16 top, int16 right, } int32 Draw::getSpriteRectSize(int16 index) { - if (_spritesArray[index] == 0) + if (!_spritesArray[index]) return 0; - return _vm->_video->getRectSize(_spritesArray[index]->width, _spritesArray[index]->height, - 0, _vm->_global->_videoMode); -} - -void Draw::initSpriteSurf(int16 index, int16 vidMode, int16 width, int16 height, int16 flags) { - if (index != 22) - _vm->_video->freeSurfDesc(_spritesArray[index]); - - _spritesArray[index] = - _vm->_video->initSurfDesc(vidMode, width, height, flags); + return _spritesArray[index]->getWidth() * _spritesArray[index]->getHeight(); } } // End of namespace Gob diff --git a/engines/gob/draw.h b/engines/gob/draw.h index 8859b93088..82b074fbee 100644 --- a/engines/gob/draw.h +++ b/engines/gob/draw.h @@ -20,18 +20,23 @@ * $Id$ * */ + #ifndef GOB_DRAW_H #define GOB_DRAW_H #include "gob/video.h" -#include "gob/global.h" namespace Gob { -#define RENDERFLAG_NOINVALIDATE 1 -#define RENDERFLAG_CAPTUREPUSH 2 -#define RENDERFLAG_CAPTUREPOP 8 -#define RENDERFLAG_USEDELTAS 0x10 +#define SPRITES_COUNT 50 + +#define RENDERFLAG_NOINVALIDATE 0x001 +#define RENDERFLAG_CAPTUREPUSH 0x002 +#define RENDERFLAG_COLLISIONS 0x004 +#define RENDERFLAG_CAPTUREPOP 0x008 +#define RENDERFLAG_USEDELTAS 0x010 +#define RENDERFLAG_NOBLITINVALIDATED 0x200 +#define RENDERFLAG_SKIPOPTIONALTEXT 0x400 class Draw { public: @@ -40,9 +45,11 @@ public: int8 base; int8 width; int8 height; - FontToSprite() : sprite(0), base(0), width(0), height() {} + FontToSprite() : sprite(0), base(0), width(0), height(0) {} }; + int16 _renderFlags; + int16 _fontIndex; int16 _spriteLeft; int16 _spriteTop; @@ -52,17 +59,21 @@ public: int16 _destSpriteY; int16 _backColor; int16 _frontColor; - char _letterToPrint; - FontToSprite _fontToSprite[4]; - int16 _destSurface; + int16 _transparency; + int16 _sourceSurface; - int16 _renderFlags; + int16 _destSurface; + + char _letterToPrint; + char *_textToPrint; + int16 _backDeltaX; int16 _backDeltaY; + + FontToSprite _fontToSprite[4]; Video::FontDesc *_fonts[8]; - char *_textToPrint; - int16 _transparency; - Video::SurfaceDesc *_spritesArray[50]; + + SurfaceDesc::Ptr _spritesArray[SPRITES_COUNT]; int16 _invalidatedCount; int16 _invalidatedTops[30]; @@ -70,16 +81,14 @@ public: int16 _invalidatedRights[30]; int16 _invalidatedBottoms[30]; - int8 _noInvalidated; -// int8 doFullFlip; // Never used?!? - int8 _paletteCleared; - - int16 _cursorIndex; - int16 _transparentCursor; - uint32 _cursorTimeKey; + bool _noInvalidated; + // Don't blit invalidated rects when in video mode 5 or 7 + bool _noInvalidated57; + bool _paletteCleared; + bool _applyPal; - Video::SurfaceDesc *_backSurface; - Video::SurfaceDesc *_frontSurface; + SurfaceDesc::Ptr _backSurface; + SurfaceDesc::Ptr _frontSurface; int16 _unusedPalette1[18]; int16 _unusedPalette2[16]; @@ -91,56 +100,57 @@ public: // 2 (10b): Cursor would be on _frontSurface // 3 (11b): Cursor would be on _backSurface and _frontSurface uint8 _showCursor; + int16 _cursorIndex; + int16 _transparentCursor; + uint32 _cursorTimeKey; int16 _cursorX; int16 _cursorY; int16 _cursorWidth; int16 _cursorHeight; - int16 _cursorXDeltaVar; - int16 _cursorYDeltaVar; + int16 _cursorHotspotXVar; + int16 _cursorHotspotYVar; - Video::SurfaceDesc *_cursorSprites; - Video::SurfaceDesc *_cursorSpritesBack; - Video::SurfaceDesc *_scummvmCursor; + SurfaceDesc::Ptr _cursorSprites; + SurfaceDesc::Ptr _cursorSpritesBack; + SurfaceDesc::Ptr _scummvmCursor; int16 _cursorAnim; int8 _cursorAnimLow[40]; int8 _cursorAnimHigh[40]; int8 _cursorAnimDelays[40]; - int8 _applyPal; int16 _palLoadData1[4]; int16 _palLoadData2[4]; - - int16 _word_2E8E2; + + int16 _needAdjust; int16 _scrollOffsetY; int16 _scrollOffsetX; - int16 _word_2E51F; - Video::SurfaceDesc *_off_2E51B; - Video::SurfaceDesc *_off_2E517; void invalidateRect(int16 left, int16 top, int16 right, int16 bottom); - void blitInvalidated(void); - void setPalette(void); - void clearPalette(void); - - void freeSprite(int16 index); + void blitInvalidated(); + void setPalette(); + void clearPalette(); + + void initSpriteSurf(int16 index, int16 width, int16 height, int16 flags); + void freeSprite(int16 index) { + assert(index < SPRITES_COUNT); + _spritesArray[index] = 0; + } void adjustCoords(char adjust, int16 *coord1, int16 *coord2); void drawString(char *str, int16 x, int16 y, int16 color1, int16 color2, - int16 transp, Video::SurfaceDesc *dest, Video::FontDesc *font); - void printTextCentered(int16 arg_0, int16 left, int16 top, int16 right, + int16 transp, SurfaceDesc *dest, Video::FontDesc *font); + void printTextCentered(int16 id, int16 left, int16 top, int16 right, int16 bottom, char *str, int16 fontIndex, int16 color); int32 getSpriteRectSize(int16 index); - void initSpriteSurf(int16 index, int16 vidMode, int16 width, int16 height, int16 flags); - virtual void initBigSprite(int16 index, int16 width, int16 height, int16 flags) = 0; - virtual void printText(void) = 0; - virtual void spriteOperation(int16 operation) = 0; - virtual void blitCursor(void) = 0; + virtual void initScreen() = 0; + virtual void closeScreen() = 0; + virtual void blitCursor() = 0; virtual void animateCursor(int16 cursor) = 0; - virtual void initScreen(void) = 0; - virtual void closeScreen(void) = 0; + virtual void printTotText(int16 id) = 0; + virtual void spriteOperation(int16 operation) = 0; Draw(GobEngine *vm); virtual ~Draw() {}; @@ -151,16 +161,12 @@ protected: class Draw_v1 : public Draw { public: - virtual void initBigSprite(int16 index, int16 width, int16 height, int16 flags) { - _vm->_draw->_spritesArray[index] = - _vm->_video->initSurfDesc(_vm->_global->_videoMode, width, height, flags); - } - virtual void printText(void); - virtual void spriteOperation(int16 operation); - virtual void blitCursor(void); + virtual void initScreen(); + virtual void closeScreen(); + virtual void blitCursor(); virtual void animateCursor(int16 cursor); - virtual void initScreen(void); - virtual void closeScreen(void); + virtual void printTotText(int16 id); + virtual void spriteOperation(int16 operation); Draw_v1(GobEngine *vm); virtual ~Draw_v1() {}; @@ -168,18 +174,12 @@ public: class Draw_v2 : public Draw_v1 { public: - virtual void initBigSprite(int16 index, int16 width, int16 height, int16 flags) { - // This would init big surfaces in pieces, to avoid breaking page bounds. - // This isn't necessary anymore, so we don't do it. - initSpriteSurf(index, _vm->_global->_videoMode, width, height, flags); - _vm->_video->clearSurf(_spritesArray[index]); - } - virtual void printText(void); - virtual void spriteOperation(int16 operation); - virtual void blitCursor(void); + virtual void initScreen(); + virtual void closeScreen(); + virtual void blitCursor(); virtual void animateCursor(int16 cursor); - virtual void initScreen(void); - virtual void closeScreen(void); + virtual void printTotText(int16 id); + virtual void spriteOperation(int16 operation); Draw_v2(GobEngine *vm); virtual ~Draw_v2() {}; @@ -187,7 +187,7 @@ public: class Draw_Bargon: public Draw_v2 { public: - virtual void initScreen(void); + virtual void initScreen(); Draw_Bargon(GobEngine *vm); virtual ~Draw_Bargon() {}; @@ -207,6 +207,6 @@ public: #define DRAW_FILLRECTABS 9 #define DRAW_DRAWLETTER 10 -} // End of namespace Gob +} // End of namespace Gob -#endif /* __DRAW_H */ +#endif // GOB_DRAW_H diff --git a/engines/gob/draw_bargon.cpp b/engines/gob/draw_bargon.cpp index c6f629d3db..8c21b41dde 100644 --- a/engines/gob/draw_bargon.cpp +++ b/engines/gob/draw_bargon.cpp @@ -21,10 +21,6 @@ * */ -#include "common/stdafx.h" -#include "common/endian.h" -#include "graphics/cursorman.h" - #include "gob/gob.h" #include "gob/draw.h" #include "gob/global.h" diff --git a/engines/gob/draw_v1.cpp b/engines/gob/draw_v1.cpp index 6a96587949..27880e1f5f 100644 --- a/engines/gob/draw_v1.cpp +++ b/engines/gob/draw_v1.cpp @@ -28,103 +28,221 @@ #include "gob/gob.h" #include "gob/draw.h" #include "gob/global.h" -#include "gob/game.h" #include "gob/util.h" -#include "gob/scenery.h" -#include "gob/inter.h" #include "gob/cdrom.h" +#include "gob/game.h" +#include "gob/scenery.h" namespace Gob { Draw_v1::Draw_v1(GobEngine *vm) : Draw(vm) { } -void Draw_v1::printText(void) { - int16 savedFlags; - int16 ldestSpriteX; - char *dataPtr; - char *ptr; - char *ptr2; - int16 index; - int16 destX; - int16 destY; - char cmd; +void Draw_v1::initScreen() { + _backSurface = _vm->_video->initSurfDesc(_vm->_global->_videoMode, 320, 200, 0); +} + +void Draw_v1::closeScreen() { +} + +void Draw_v1::blitCursor() { + if (_cursorIndex == -1) + return; + + if (_showCursor == 2) + _showCursor = 0; +} + +void Draw_v1::animateCursor(int16 cursor) { + Game::Collision *ptr; + int16 cursorIndex = cursor; + int16 newX = 0, newY = 0; + uint16 hotspotX = 0, hotspotY = 0; + + _showCursor = 2; + + if (cursorIndex == -1) { + cursorIndex = 0; + for (ptr = _vm->_game->_collisionAreas; ptr->left != -1; ptr++) { + if (ptr->flags & 0xFFF0) + continue; + + if (ptr->left > _vm->_global->_inter_mouseX) + continue; + + if (ptr->right < _vm->_global->_inter_mouseX) + continue; + + if (ptr->top > _vm->_global->_inter_mouseY) + continue; + + if (ptr->bottom < _vm->_global->_inter_mouseY) + continue; + + if ((ptr->flags & 0xF) < 3) + cursorIndex = 1; + else + cursorIndex = 3; + break; + } + if (_cursorAnimLow[cursorIndex] == -1) + cursorIndex = 1; + } + + if (_cursorAnimLow[cursorIndex] != -1) { + if (cursorIndex == _cursorIndex) { + if (_cursorAnimDelays[_cursorIndex] != 0 && + _cursorAnimDelays[_cursorIndex] * 10 + + _cursorTimeKey <= _vm->_util->getTimeKey()) { + _cursorAnim++; + _cursorTimeKey = _vm->_util->getTimeKey(); + } else { + if (_noInvalidated && (_vm->_global->_inter_mouseX == _cursorX) && + (_vm->_global->_inter_mouseY == _cursorY)) { + _vm->_video->waitRetrace(_vm->_global->_videoMode); + return; + } + } + } else { + _cursorIndex = cursorIndex; + if (_cursorAnimDelays[_cursorIndex] != 0) { + _cursorAnim = + _cursorAnimLow[_cursorIndex]; + _cursorTimeKey = _vm->_util->getTimeKey(); + } else { + _cursorAnim = _cursorIndex; + } + } + + if (_cursorAnimDelays[_cursorIndex] != 0 && + (_cursorAnimHigh[_cursorIndex] < _cursorAnim || + _cursorAnimLow[_cursorIndex] > + _cursorAnim)) { + _cursorAnim = _cursorAnimLow[_cursorIndex]; + } + + newX = _vm->_global->_inter_mouseX; + newY = _vm->_global->_inter_mouseY; + if (_cursorHotspotXVar != -1) { + newX -= hotspotX = (uint16) VAR(_cursorIndex + _cursorHotspotXVar); + newY -= hotspotY = (uint16) VAR(_cursorIndex + _cursorHotspotYVar); + } + + _vm->_video->clearSurf(_scummvmCursor); + _vm->_video->drawSprite(_cursorSprites, _scummvmCursor, + cursorIndex * _cursorWidth, 0, + (cursorIndex + 1) * _cursorWidth - 1, + _cursorHeight - 1, 0, 0, 0); + CursorMan.replaceCursor(_scummvmCursor->getVidMem(), + _cursorWidth, _cursorHeight, hotspotX, hotspotY, 0); + + if (_frontSurface != _backSurface) { + _showCursor = 3; + if (!_noInvalidated) { + int16 tmp = _cursorIndex; + _cursorIndex = -1; + blitInvalidated(); + _cursorIndex = tmp; + } else { + _vm->_video->waitRetrace(_vm->_global->_videoMode); + if (MIN(newY, _cursorY) < 50) + _vm->_util->delay(5); + _showCursor = 0; + } + } + } else + blitCursor(); + + _cursorX = newX; + _cursorY = newY; +} + +void Draw_v1::printTotText(int16 id) { + byte *dataPtr; + byte *ptr, *ptrEnd; + byte cmd; + int16 destX, destY; int16 val; + int16 savedFlags; + int16 destSpriteX; + int16 spriteRight, spriteBottom; char buf[20]; - index = _vm->_inter->load16(); - _vm->_cdrom->playMultMusic(); - dataPtr = _vm->_game->_totTextData->dataPtr + _vm->_game->_totTextData->items[index].offset; + if (!_vm->_game->_totTextData || !_vm->_game->_totTextData->dataPtr) + return; + + dataPtr = ((byte *) _vm->_game->_totTextData->dataPtr) + + _vm->_game->_totTextData->items[id].offset; ptr = dataPtr; + destX = READ_LE_UINT16(ptr) & 0x7FFF; + destY = READ_LE_UINT16(ptr + 2); + spriteRight = READ_LE_UINT16(ptr + 4); + spriteBottom = READ_LE_UINT16(ptr + 6); + ptr += 8; + if (_renderFlags & RENDERFLAG_CAPTUREPUSH) { - _destSpriteX = READ_LE_UINT16(ptr); - _destSpriteY = READ_LE_UINT16(ptr + 2); - _spriteRight = READ_LE_UINT16(ptr + 4) - _destSpriteX + 1; - _spriteBottom = READ_LE_UINT16(ptr + 6) - _destSpriteY + 1; - _vm->_game->capturePush(_destSpriteX, _destSpriteY, - _spriteRight, _spriteBottom); + _vm->_game->capturePush(destX, destY, + spriteRight - destX + 1, spriteBottom - destY + 1); (*_vm->_scenery->_pCaptureCounter)++; } - _destSpriteX = READ_LE_UINT16(ptr); - destX = _destSpriteX; - - _destSpriteY = READ_LE_UINT16(ptr + 2); - destY = _destSpriteY; - _spriteRight = READ_LE_UINT16(ptr + 4); - _spriteBottom = READ_LE_UINT16(ptr + 6); + _destSpriteX = destX; + _destSpriteY = destY; + _spriteRight = spriteRight; + _spriteBottom = spriteBottom; _destSurface = 21; - ptr += 8; - _backColor = *ptr++; _transparency = 1; spriteOperation(DRAW_CLEARRECT); _backColor = 0; savedFlags = _renderFlags; - _renderFlags &= ~RENDERFLAG_NOINVALIDATE; - for (; (_destSpriteX = READ_LE_UINT16(ptr)) != -1; ptr++) { + + while ((_destSpriteX = READ_LE_UINT16(ptr)) != -1) { _destSpriteX += destX; _destSpriteY = READ_LE_UINT16(ptr + 2) + destY; _spriteRight = READ_LE_UINT16(ptr + 4) + destX; _spriteBottom = READ_LE_UINT16(ptr + 6) + destY; ptr += 8; - cmd = (*ptr & 0xf0) >> 4; - if (cmd == 0) { - _frontColor = *ptr & 0xf; + cmd = *ptr++; + switch ((cmd & 0xF0) >> 4) { + case 0: + _frontColor = cmd & 0xF; spriteOperation(DRAW_DRAWLINE); - } else if (cmd == 1) { - _frontColor = *ptr & 0xf; + break; + case 1: + _frontColor = cmd & 0xF; spriteOperation(DRAW_DRAWBAR); - } else if (cmd == 2) { - _backColor = *ptr & 0xf; + break; + case 2: + _backColor = cmd & 0xF; spriteOperation(DRAW_FILLRECTABS); + break; } } ptr += 2; - for (ptr2 = ptr; *ptr2 != 1; ptr2++) { - if (*ptr2 == 3) - ptr2++; + for (ptrEnd = ptr; *ptrEnd != 1; ptrEnd++) { + if (*ptrEnd == 3) + ptrEnd++; - if (*ptr2 == 2) - ptr2 += 4; + if (*ptrEnd == 2) + ptrEnd += 4; } - - ptr2++; + ptrEnd++; while (*ptr != 1) { cmd = *ptr; if (cmd == 3) { ptr++; - _fontIndex = (*ptr & 0xf0) >> 4; - _frontColor = *ptr & 0xf; + _fontIndex = (*ptr & 0xF0) >> 4; + _frontColor = *ptr & 0xF; ptr++; continue; } else if (cmd == 2) { @@ -135,42 +253,42 @@ void Draw_v1::printText(void) { continue; } - if ((byte)*ptr != 0xba) { - _letterToPrint = *ptr; + if (*ptr != 0xBA) { + _letterToPrint = (char) *ptr; spriteOperation(DRAW_DRAWLETTER); _destSpriteX += _fonts[_fontIndex]->itemWidth; ptr++; } else { - cmd = ptr2[17] & 0x7f; + cmd = ptrEnd[17] & 0x7F; if (cmd == 0) { - val = READ_LE_UINT16(ptr2 + 18) * 4; - sprintf(buf, "%d", VAR_OFFSET(val)); + val = READ_LE_UINT16(ptrEnd + 18) * 4; + sprintf(buf, "%d", VAR_OFFSET(val)); } else if (cmd == 1) { - val = READ_LE_UINT16(ptr2 + 18) * 4; + val = READ_LE_UINT16(ptrEnd + 18) * 4; strcpy(buf, GET_VARO_STR(val)); } else { - val = READ_LE_UINT16(ptr2 + 18) * 4; + val = READ_LE_UINT16(ptrEnd + 18) * 4; - sprintf(buf, "%d", VAR_OFFSET(val)); + sprintf(buf, "%d", VAR_OFFSET(val)); if (buf[0] == '-') { - while (strlen(buf) - 1 < (uint32)ptr2[17]) { + while (strlen(buf) - 1 < (uint32)ptrEnd[17]) { _vm->_util->insertStr("0", buf, 1); } } else { - while (strlen(buf) - 1 < (uint32)ptr2[17]) { + while (strlen(buf) - 1 < (uint32)ptrEnd[17]) { _vm->_util->insertStr("0", buf, 0); } } - _vm->_util->insertStr(",", buf, strlen(buf) + 1 - ptr2[17]); + _vm->_util->insertStr(",", buf, strlen(buf) + 1 - ptrEnd[17]); } _textToPrint = buf; - ldestSpriteX = _destSpriteX; + destSpriteX = _destSpriteX; spriteOperation(DRAW_PRINTTEXT); - if (ptr2[17] & 0x80) { + if (ptrEnd[17] & 0x80) { if (ptr[1] == ' ') { _destSpriteX += _fonts[_fontIndex]->itemWidth; while (ptr[1] == ' ') @@ -184,29 +302,16 @@ void Draw_v1::printText(void) { _destSpriteX += _fonts[_fontIndex]->itemWidth; } } else { - _destSpriteX = ldestSpriteX + _fonts[_fontIndex]->itemWidth; + _destSpriteX = destSpriteX + _fonts[_fontIndex]->itemWidth; } - ptr2 += 23; + ptrEnd += 23; ptr++; } } _renderFlags = savedFlags; - if (_renderFlags & 4) { - warning("printText: Input not supported"); -// xor ax, ax -// loc_436_1391: -// xor dx, dx -// push ax -// push dx -// push ax -// push dx -// push ax -// mov al, 0 -// push ax -// call sub_9FF_1E71 -// add sp, 0Ch - } + if (_renderFlags & RENDERFLAG_COLLISIONS) + _vm->_game->checkCollisions(0, 0, 0, 0); if ((_renderFlags & RENDERFLAG_CAPTUREPOP) && *_vm->_scenery->_pCaptureCounter != 0) { (*_vm->_scenery->_pCaptureCounter)--; @@ -220,14 +325,11 @@ void Draw_v1::spriteOperation(int16 operation) { Game::TotResItem *itemPtr; int32 offset; int16 len; - int16 i; - int16 x; - int16 y; + int16 x, y; int16 perLine; if (_sourceSurface >= 100) _sourceSurface -= 80; - if (_destSurface >= 100) _destSurface -= 80; @@ -240,9 +342,9 @@ void Draw_v1::spriteOperation(int16 operation) { if (_destSurface == 21) { _destSpriteX += _backDeltaX; _destSpriteY += _backDeltaY; - if (operation == DRAW_DRAWLINE || - (operation >= DRAW_DRAWBAR - && operation <= DRAW_FILLRECTABS)) { + if ((operation == DRAW_DRAWLINE) || + ((operation >= DRAW_DRAWBAR) && + (operation <= DRAW_FILLRECTABS))) { _spriteRight += _backDeltaX; _spriteBottom += _backDeltaY; } @@ -260,8 +362,8 @@ void Draw_v1::spriteOperation(int16 operation) { if (_destSurface == 21) { invalidateRect(_destSpriteX, _destSpriteY, - _destSpriteX + _spriteRight - 1, - _destSpriteY + _spriteBottom - 1); + _destSpriteX + _spriteRight - 1, + _destSpriteY + _spriteBottom - 1); } break; @@ -270,7 +372,7 @@ void Draw_v1::spriteOperation(int16 operation) { _frontColor, _spritesArray[_destSurface]); if (_destSurface == 21) { invalidateRect(_destSpriteX, _destSpriteY, - _destSpriteX, _destSpriteY); + _destSpriteX, _destSpriteY); } break; @@ -282,8 +384,8 @@ void Draw_v1::spriteOperation(int16 operation) { if (_destSurface == 21) { invalidateRect(_destSpriteX, _destSpriteY, - _destSpriteX + _spriteRight - 1, - _destSpriteY + _spriteBottom - 1); + _destSpriteX + _spriteRight - 1, + _destSpriteY + _spriteBottom - 1); } break; @@ -294,15 +396,16 @@ void Draw_v1::spriteOperation(int16 operation) { if (_destSurface == 21) { invalidateRect(_destSpriteX, _destSpriteY, - _spriteRight, _spriteBottom); + _spriteRight, _spriteBottom); } break; case DRAW_INVALIDATE: if (_destSurface == 21) { - invalidateRect(_destSpriteX - _spriteRight, _destSpriteY - _spriteBottom, // !! - _destSpriteX + _spriteRight, - _destSpriteY + _spriteBottom); + invalidateRect(_destSpriteX - _spriteRight, + _destSpriteY - _spriteBottom, + _destSpriteX + _spriteRight, + _destSpriteY + _spriteBottom); } break; @@ -310,17 +413,15 @@ void Draw_v1::spriteOperation(int16 operation) { id = _spriteLeft; if (id >= 30000) { dataBuf = - _vm->_game->loadExtData(id, &_spriteRight, - &_spriteBottom); - _vm->_video->drawPackedSprite((byte *)dataBuf, _spriteRight, - _spriteBottom, _destSpriteX, - _destSpriteY, _transparency, - _spritesArray[_destSurface]); + _vm->_game->loadExtData(id, &_spriteRight, &_spriteBottom); + _vm->_video->drawPackedSprite((byte *) dataBuf, + _spriteRight, _spriteBottom, + _destSpriteX, _destSpriteY, + _transparency, _spritesArray[_destSurface]); if (_destSurface == 21) { - invalidateRect(_destSpriteX, - _destSpriteY, - _destSpriteX + _spriteRight - 1, - _destSpriteY + _spriteBottom - 1); + invalidateRect(_destSpriteX, _destSpriteY, + _destSpriteX + _spriteRight - 1, + _destSpriteY + _spriteBottom - 1); } delete[] dataBuf; break; @@ -333,27 +434,25 @@ void Draw_v1::spriteOperation(int16 operation) { itemPtr = &_vm->_game->_totResourceTable->items[id]; offset = itemPtr->offset; if (offset >= 0) { - dataBuf = - _vm->_game->_totResourceTable->dataPtr + + dataBuf = _vm->_game->_totResourceTable->dataPtr + szGame_TotResTable + szGame_TotResItem * _vm->_game->_totResourceTable->itemsCount + offset; } else { - dataBuf = - _vm->_game->_imFileData + - (int32)READ_LE_UINT32(&((int32 *)_vm->_game->_imFileData)[-offset - 1]); + dataBuf = _vm->_game->_imFileData + + (int32) READ_LE_UINT32(&((int32 *) _vm->_game->_imFileData)[-offset - 1]); } _spriteRight = itemPtr->width; _spriteBottom = itemPtr->height; - _vm->_video->drawPackedSprite((byte *)dataBuf, + _vm->_video->drawPackedSprite((byte *) dataBuf, _spriteRight, _spriteBottom, _destSpriteX, _destSpriteY, _transparency, _spritesArray[_destSurface]); if (_destSurface == 21) { invalidateRect(_destSpriteX, _destSpriteY, - _destSpriteX + _spriteRight - 1, - _destSpriteY + _spriteBottom - 1); + _destSpriteX + _spriteRight - 1, + _destSpriteY + _spriteBottom - 1); } break; @@ -361,13 +460,11 @@ void Draw_v1::spriteOperation(int16 operation) { len = strlen(_textToPrint); if (_destSurface == 21) { invalidateRect(_destSpriteX, _destSpriteY, - _destSpriteX + - len * _fonts[_fontIndex]->itemWidth - 1, - _destSpriteY + - _fonts[_fontIndex]->itemHeight - 1); + _destSpriteX + len * _fonts[_fontIndex]->itemWidth - 1, + _destSpriteY + _fonts[_fontIndex]->itemHeight - 1); } - for (i = 0; i < len; i++) { + for (int i = 0; i < len; i++) { _vm->_video->drawLetter(_textToPrint[i], _destSpriteX, _destSpriteY, _fonts[_fontIndex], @@ -398,7 +495,7 @@ void Draw_v1::spriteOperation(int16 operation) { if (_destSurface == 21) { invalidateRect(_destSpriteX, _destSpriteY, - _spriteRight, _spriteBottom); + _spriteRight, _spriteBottom); } break; @@ -411,7 +508,7 @@ void Draw_v1::spriteOperation(int16 operation) { } if (_destSurface == 21) { invalidateRect(_destSpriteX, _destSpriteY, - _spriteRight, _spriteBottom); + _spriteRight, _spriteBottom); } break; @@ -422,7 +519,7 @@ void Draw_v1::spriteOperation(int16 operation) { if (_destSurface == 21) { invalidateRect(_destSpriteX, _destSpriteY, - _spriteRight, _spriteBottom); + _spriteRight, _spriteBottom); } break; @@ -431,11 +528,8 @@ void Draw_v1::spriteOperation(int16 operation) { if (_destSurface == 21) { invalidateRect(_destSpriteX, _destSpriteY, - _destSpriteX + - _fonts[_fontIndex]->itemWidth - 1, - _destSpriteY + - _fonts[_fontIndex]->itemHeight - - 1); + _destSpriteX + _fonts[_fontIndex]->itemWidth - 1, + _destSpriteY + _fonts[_fontIndex]->itemHeight - 1); } _vm->_video->drawLetter(_letterToPrint, _destSpriteX, _destSpriteY, @@ -447,27 +541,22 @@ void Draw_v1::spriteOperation(int16 operation) { } perLine = - _spritesArray[(int16)_fontToSprite[_fontIndex]. - sprite]->width / _fontToSprite[_fontIndex].width; + _spritesArray[(int16)_fontToSprite[_fontIndex].sprite]->getWidth() / + _fontToSprite[_fontIndex].width; - y = (_letterToPrint - - _fontToSprite[_fontIndex].base) / perLine * - _fontToSprite[_fontIndex].height; + y = (_letterToPrint - _fontToSprite[_fontIndex].base) / perLine * + _fontToSprite[_fontIndex].height; - x = (_letterToPrint - - _fontToSprite[_fontIndex].base) % perLine * - _fontToSprite[_fontIndex].width; + x = (_letterToPrint - _fontToSprite[_fontIndex].base) % perLine * + _fontToSprite[_fontIndex].width; if (_destSurface == 21) { invalidateRect(_destSpriteX, _destSpriteY, - _destSpriteX + - _fontToSprite[_fontIndex].width, - _destSpriteY + - _fontToSprite[_fontIndex].height); + _destSpriteX + _fontToSprite[_fontIndex].width, + _destSpriteY + _fontToSprite[_fontIndex].height); } - _vm->_video->drawSprite(_spritesArray[(int16)_fontToSprite - [_fontIndex].sprite], + _vm->_video->drawSprite(_spritesArray[(int16)_fontToSprite[_fontIndex].sprite], _spritesArray[_destSurface], x, y, x + _fontToSprite[_fontIndex].width, y + _fontToSprite[_fontIndex].height, @@ -489,129 +578,4 @@ void Draw_v1::spriteOperation(int16 operation) { } } -void Draw_v1::blitCursor(void) { - if (_cursorIndex == -1) - return; - - if (_showCursor == 2) - _showCursor = 0; -} - -void Draw_v1::animateCursor(int16 cursor) { - int16 newX = 0; - int16 newY = 0; - Game::Collision *ptr; - int16 minX; - int16 minY; - int16 maxX; - int16 maxY; - int16 cursorIndex; - - _showCursor = 2; - cursorIndex = cursor; - - if (cursorIndex == -1) { - cursorIndex = 0; - for (ptr = _vm->_game->_collisionAreas; ptr->left != -1; ptr++) { - if (ptr->flags & 0xfff0) - continue; - - if (ptr->left > _vm->_global->_inter_mouseX) - continue; - - if (ptr->right < _vm->_global->_inter_mouseX) - continue; - - if (ptr->top > _vm->_global->_inter_mouseY) - continue; - - if (ptr->bottom < _vm->_global->_inter_mouseY) - continue; - - if ((ptr->flags & 0xf) < 3) - cursorIndex = 1; - else - cursorIndex = 3; - break; - } - if (_cursorAnimLow[cursorIndex] == -1) - cursorIndex = 1; - } - - if (_cursorAnimLow[cursorIndex] != -1) { - if (cursorIndex == _cursorIndex) { - if (_cursorAnimDelays[_cursorIndex] != 0 && - _cursorAnimDelays[_cursorIndex] * 10 + - _cursorTimeKey <= _vm->_util->getTimeKey()) { - _cursorAnim++; - _cursorTimeKey = _vm->_util->getTimeKey(); - } else { - if ((_noInvalidated != 0) && (_vm->_global->_inter_mouseX == _cursorX) && - (_vm->_global->_inter_mouseY == _cursorY)) { - _vm->_video->waitRetrace(_vm->_global->_videoMode); - return; - } - } - } else { - _cursorIndex = cursorIndex; - if (_cursorAnimDelays[_cursorIndex] != 0) { - _cursorAnim = - _cursorAnimLow[_cursorIndex]; - _cursorTimeKey = _vm->_util->getTimeKey(); - } else { - _cursorAnim = _cursorIndex; - } - } - - if (_cursorAnimDelays[_cursorIndex] != 0 && - (_cursorAnimHigh[_cursorIndex] < _cursorAnim || - _cursorAnimLow[_cursorIndex] > - _cursorAnim)) { - _cursorAnim = _cursorAnimLow[_cursorIndex]; - } - - newX = _vm->_global->_inter_mouseX; - newY = _vm->_global->_inter_mouseY; - if (_cursorXDeltaVar != -1) { - newX -= (uint16)VAR_OFFSET(_cursorIndex * 4 + (_cursorXDeltaVar / 4) * 4); - newY -= (uint16)VAR_OFFSET(_cursorIndex * 4 + (_cursorYDeltaVar / 4) * 4); - } - - minX = MIN(newX, _cursorX); - minY = MIN(newY, _cursorY); - maxX = MAX(_cursorX, newX) + _cursorWidth - 1; - maxY = MAX(_cursorY, newY) + _cursorHeight - 1; - - _vm->_video->drawSprite(_cursorSprites, _scummvmCursor, _cursorWidth * _cursorAnim, - 0, _cursorWidth * (_cursorAnim + 1) - 1, _cursorHeight - 1, 0, 0, 0); - CursorMan.replaceCursor(_scummvmCursor->vidPtr, _cursorWidth, _cursorHeight, 0, 0, 0); - - if (_frontSurface != _backSurface) { - _showCursor = 3; - if (_noInvalidated == 0) { - int16 tmp = _cursorIndex; - _cursorIndex = -1; - blitInvalidated(); - _cursorIndex = tmp; - } else { - _vm->_video->waitRetrace(_vm->_global->_videoMode); - if (minY < 50) - _vm->_util->delay(5); - _showCursor = 0; - } - } - } else - blitCursor(); - - _cursorX = newX; - _cursorY = newY; -} - -void Draw_v1::initScreen(void) { - _backSurface = _vm->_video->initSurfDesc(_vm->_global->_videoMode, 320, 200, 0); -} - -void Draw_v1::closeScreen(void) { -} - } // End of namespace Gob diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp index 500dcb586c..93cfe04be9 100644 --- a/engines/gob/draw_v2.cpp +++ b/engines/gob/draw_v2.cpp @@ -28,69 +28,184 @@ #include "gob/gob.h" #include "gob/draw.h" #include "gob/global.h" -#include "gob/game.h" #include "gob/util.h" +#include "gob/game.h" #include "gob/scenery.h" -#include "gob/inter.h" -#include "gob/cdrom.h" +#include "gob/video.h" namespace Gob { Draw_v2::Draw_v2(GobEngine *vm) : Draw_v1(vm) { } -void Draw_v2::printText(void) { - int i; +void Draw_v2::initScreen() { + _scrollOffsetX = 0; + _scrollOffsetY = 0; + + initSpriteSurf(21, _vm->_video->_surfWidth, _vm->_video->_surfHeight, 0); + _backSurface = _spritesArray[21]; + _vm->_video->clearSurf(_backSurface); + + initSpriteSurf(23, 32, 16, 2); + _cursorSpritesBack = _spritesArray[23]; + _cursorSprites = _cursorSpritesBack; + _scummvmCursor = + _vm->_video->initSurfDesc(_vm->_global->_videoMode, 16, 16, SCUMMVM_CURSOR); + + _spritesArray[20] = _frontSurface; + _spritesArray[21] = _backSurface; +} + +void Draw_v2::closeScreen() { + freeSprite(23); + _cursorSprites = 0; + _cursorSpritesBack = 0; + _scummvmCursor = 0; + freeSprite(21); +} + +void Draw_v2::blitCursor() { + if (_cursorIndex == -1) + return; + + _showCursor = (_showCursor & ~2) | ((_showCursor & 1) << 1); +} + +void Draw_v2::animateCursor(int16 cursor) { + Game::Collision *ptr; + int16 cursorIndex = cursor; + int16 newX = 0, newY = 0; + uint16 hotspotX = 0, hotspotY = 0; + + _showCursor |= 1; + + // .-- _draw_animateCursorSUB1 --- + if (cursorIndex == -1) { + cursorIndex = 0; + for (ptr = _vm->_game->_collisionAreas; ptr->left != -1; ptr++) { + if ((ptr->flags & 0xF00) || (ptr->id & 0x4000)) + continue; + + if (ptr->left > _vm->_global->_inter_mouseX) + continue; + + if (ptr->right < _vm->_global->_inter_mouseX) + continue; + + if (ptr->top > _vm->_global->_inter_mouseY) + continue; + + if (ptr->bottom < _vm->_global->_inter_mouseY) + continue; + + if ((ptr->flags & 0xF000) == 0) { + if ((ptr->flags & 0xF) >= 3) { + cursorIndex = 3; + break; + } else if (((ptr->flags & 0xF0) != 0x10) && (cursorIndex == 0)) + cursorIndex = 1; + } else if (cursorIndex == 0) + cursorIndex = (ptr->flags >> 12) & 0xF; + } + if (_cursorAnimLow[cursorIndex] == -1) + cursorIndex = 1; + } + // '------ + + if (_cursorAnimLow[cursorIndex] != -1) { + // .-- _draw_animateCursorSUB2 --- + if (cursorIndex == _cursorIndex) { + if ((_cursorAnimDelays[_cursorIndex] != 0) && + ((_cursorTimeKey + (_cursorAnimDelays[_cursorIndex] * 10)) <= + _vm->_util->getTimeKey())) { + _cursorAnim++; + if ((_cursorAnimHigh[_cursorIndex] < _cursorAnim) || + (_cursorAnimLow[_cursorIndex] > _cursorAnim)) + _cursorAnim = _cursorAnimLow[_cursorIndex]; + _cursorTimeKey = _vm->_util->getTimeKey(); + } else { + if (_noInvalidated && (_vm->_global->_inter_mouseX == _cursorX) && + (_vm->_global->_inter_mouseY == _cursorY)) { + _vm->_video->waitRetrace(_vm->_global->_videoMode); + return; + } + } + } else { + _cursorIndex = cursorIndex; + if (_cursorAnimDelays[cursorIndex] != 0) { + _cursorAnim = _cursorAnimLow[cursorIndex]; + _cursorTimeKey = _vm->_util->getTimeKey(); + } + } + + if (_cursorAnimDelays[_cursorIndex] != 0) { + if ((_cursorAnimHigh[_cursorIndex] < _cursorAnim) || + (_cursorAnimLow[_cursorIndex] > _cursorAnim)) + _cursorAnim = _cursorAnimLow[_cursorIndex]; + + cursorIndex = _cursorAnim; + } + // '------ + + newX = _vm->_global->_inter_mouseX; + newY = _vm->_global->_inter_mouseY; + if (_cursorHotspotXVar != -1) { + newX -= hotspotX = (uint16) VAR(_cursorIndex + _cursorHotspotXVar); + newY -= hotspotY = (uint16) VAR(_cursorIndex + _cursorHotspotYVar); + } + + _vm->_video->clearSurf(_scummvmCursor); + _vm->_video->drawSprite(_cursorSprites, _scummvmCursor, + cursorIndex * _cursorWidth, 0, + (cursorIndex + 1) * _cursorWidth - 1, + _cursorHeight - 1, 0, 0, 0); + CursorMan.replaceCursor(_scummvmCursor->getVidMem(), + _cursorWidth, _cursorHeight, hotspotX, hotspotY, 0); + + if (_frontSurface != _backSurface) { + if (!_noInvalidated) { + int16 tmp = _cursorIndex; + _cursorIndex = -1; + blitInvalidated(); + _cursorIndex = tmp; + } else { + _showCursor = 3; + _vm->_video->waitRetrace(_vm->_global->_videoMode); + if (MIN(newY, _cursorY) < 50) + _vm->_util->delay(5); + } + } + } else + blitCursor(); + + _showCursor &= ~1; + + _cursorX = newX; + _cursorY = newY; +} + +void Draw_v2::printTotText(int16 id) { byte *dataPtr; - byte *ptr; - byte *ptr2; - char mask[80]; - char str[80]; - char buf[50]; - char cmd; + byte *ptr, *ptrEnd; + byte cmd; int16 savedFlags; - int16 destX; - int16 destY; - int16 spriteRight; - int16 spriteBottom; + int16 destX, destY; + int16 spriteRight, spriteBottom; int16 val; - int16 index; - int16 rectLeft; - int16 rectTop; - int16 rectRight; - int16 rectBottom; - int16 fontIndex; - int16 strPos; // si - int16 frontColor; - int16 colId; - int16 strPos2; - int16 offX; - int16 offY; - int16 extraCmd; - int16 strPosBak; - int16 maskChar; - int16 width; + int16 rectLeft, rectTop, rectRight, rectBottom; int16 size; - index = _vm->_inter->load16(); - - _vm->_cdrom->playMultMusic(); - - if ((_vm->_game->_totTextData == 0) || (_vm->_game->_totTextData->dataPtr == 0)) + if (!_vm->_game->_totTextData || !_vm->_game->_totTextData->dataPtr) return; - if (_vm->_global->_languageWanted != _vm->_global->_language) { - warning("Your game version doesn't support the requested language, " - "using the first one available (%d)", _vm->_global->_language); - _vm->_global->_languageWanted = _vm->_global->_language; - } + _vm->validateLanguage(); - size = _vm->_game->_totTextData->items[index].size; + size = _vm->_game->_totTextData->items[id].size; dataPtr = ((byte *) _vm->_game->_totTextData->dataPtr) + - _vm->_game->_totTextData->items[index].offset; + _vm->_game->_totTextData->items[id].offset; ptr = dataPtr; - if ((_renderFlags & 0x400) && (ptr[1] & 0x80)) + if ((_renderFlags & RENDERFLAG_SKIPOPTIONALTEXT) && (ptr[1] & 0x80)) return; destX = READ_LE_UINT16(ptr) & 0x7FFF; @@ -117,92 +232,94 @@ void Draw_v2::printText(void) { spriteOperation(DRAW_CLEARRECT); _backColor = 0; - savedFlags = _renderFlags; _renderFlags &= ~RENDERFLAG_NOINVALIDATE; - for (; (_destSpriteX = READ_LE_UINT16(ptr)) != -1; ptr++) { + while ((_destSpriteX = READ_LE_UINT16(ptr)) != -1) { _destSpriteX += destX; _destSpriteY = READ_LE_UINT16(ptr + 2) + destY; _spriteRight = READ_LE_UINT16(ptr + 4) + destX; _spriteBottom = READ_LE_UINT16(ptr + 6) + destY; ptr += 8; - cmd = (*ptr & 0xf0) >> 4; - if (cmd == 0) { - _frontColor = *ptr & 0xf; + cmd = *ptr++; + switch ((cmd & 0xF0) >> 4) { + case 0: + _frontColor = cmd & 0xF; spriteOperation(DRAW_DRAWLINE); - } else if (cmd == 1) { - _frontColor = *ptr & 0xf; + break; + case 1: + _frontColor = cmd & 0xF; spriteOperation(DRAW_DRAWBAR); - } else if (cmd == 2) { - _backColor = *ptr & 0xf; + break; + case 2: + _backColor = cmd & 0xF; spriteOperation(DRAW_FILLRECTABS); + break; } } ptr += 2; - // Adding the boundary check *shouldn't* pose any problems, since access behind - // that point should be forbidden anyway. - for (i = 0, ptr2 = ptr; ((ptr2 - dataPtr) < size) && (*ptr2 != 1); i++) { - if ((_vm->_game->_totFileData[0x29] < 0x32) && (*ptr2 > 3) && (*ptr2 < 32)) - *ptr2 = 32; + ptrEnd = ptr; + while (((ptrEnd - dataPtr) < size) && (*ptrEnd != 1)) { + // Converting to unknown commands/characters to spaces + if ((_vm->_game->_totFileData[0x29] < 0x32) && (*ptrEnd > 3) && (*ptrEnd < 32)) + *ptrEnd = 32; - switch (*ptr2) { + switch (*ptrEnd) { case 1: break; case 2: case 5: - ptr2 += 5; + ptrEnd += 5; break; case 3: case 4: - ptr2 += 2; + ptrEnd += 2; break; case 6: - ptr2++; - switch (*ptr2 & 0xC0) { + ptrEnd++; + switch (*ptrEnd & 0xC0) { case 0x40: - ptr2 += 9; + ptrEnd += 9; break; case 0x80: - ptr2 += 3; + ptrEnd += 3; break; case 0xC0: - ptr2 += 11; + ptrEnd += 11; break; default: - ptr2++; + ptrEnd++; break; } break; case 10: - ptr2 += (ptr2[1] * 2) + 2; + ptrEnd += (ptrEnd[1] * 2) + 2; break; default: - ptr2++; + ptrEnd++; break; } } + ptrEnd++; - ptr2++; + int16 fontIndex = 0, frontColor = 0; + int16 strPos = 0, strPos2 = -1, strPosBak; + int16 offX = 0, offY = 0; + int16 colId = 0; + int16 colCmd = 0; + int16 width; + int16 maskChar = 0; + char mask[80], str[80], buf[50]; - fontIndex = 0; - strPos = 0; - extraCmd = 0; - frontColor = 0; - colId = 0; - offX = 0; - offY = 0; - strPos2 = -1; memset(mask, 0, 80); memset(str, ' ', 80); - maskChar = 0; _backColor = 0; _transparency = 1; @@ -212,7 +329,8 @@ void Draw_v2::printText(void) { strPosBak = strPos; width = strlen(str) * _fonts[fontIndex]->itemWidth; adjustCoords(1, &width, 0); - if (extraCmd & 0x0F) { + + if (colCmd & 0x0F) { rectLeft = offX - 2; rectTop = offY - 2; rectRight = offX + width + 1; @@ -221,36 +339,42 @@ void Draw_v2::printText(void) { rectBottom += offY + 1; adjustCoords(0, &rectLeft, &rectTop); adjustCoords(2, &rectRight, &rectBottom); + if (colId != -1) _vm->_game->addNewCollision(colId + 0xD000, rectLeft, rectTop, rectRight, rectBottom, 2, 0, 0, 0); - if (_word_2E8E2 != 2) - printTextCentered(extraCmd & 0x0F, rectLeft + 4, rectTop + 4, + + if (_needAdjust != 2) + printTextCentered(colCmd & 0x0F, rectLeft + 4, rectTop + 4, rectRight - 4, rectBottom - 4, str, fontIndex, frontColor); else - printTextCentered(extraCmd & 0x0F, rectLeft + 2, rectTop + 2, + printTextCentered(colCmd & 0x0F, rectLeft + 2, rectTop + 2, rectRight - 2, rectBottom - 2, str, fontIndex, frontColor); + } else { _destSpriteX = offX; _destSpriteY = offY; _fontIndex = fontIndex; _frontColor = frontColor; _textToPrint = str; - if (_word_2E8E2 != 2) { - if ((_destSpriteX >= destX) && (_destSpriteY >= destY)) { - if (((_fonts[_fontIndex]->itemHeight / 2) + _destSpriteY - 1) <= spriteBottom) { - while (((_destSpriteX + width - 1) > spriteRight) && (width > 0)) { - width -= _fonts[_fontIndex]->itemWidth / 2; - str[strlen(str) - 1] = '\0'; - } - spriteOperation(DRAW_PRINTTEXT); + + if (_needAdjust != 2) { + if ((_destSpriteX >= destX) && (_destSpriteY >= destY) && + (((_fonts[_fontIndex]->itemHeight / 2) + _destSpriteY - 1) <= spriteBottom)) { + while (((_destSpriteX + width - 1) > spriteRight) && (width > 0)) { + width -= _fonts[_fontIndex]->itemWidth / 2; + str[strlen(str) - 1] = '\0'; } + spriteOperation(DRAW_PRINTTEXT); } } else spriteOperation(DRAW_PRINTTEXT); + width = strlen(str); for (strPos = 0; strPos < width; strPos++) { - if (mask[strPos] == '\0') continue; + if (mask[strPos] == '\0') + continue; + rectLeft = _fonts[fontIndex]->itemWidth; rectTop = _fonts[fontIndex]->itemHeight; adjustCoords(1, &rectLeft, &rectTop); @@ -261,6 +385,7 @@ void Draw_v2::printText(void) { spriteOperation(DRAW_DRAWLINE); } } + rectLeft = _fonts[_fontIndex]->itemWidth; adjustCoords(1, &rectLeft, 0); offX += strPosBak * rectLeft; @@ -297,13 +422,13 @@ void Draw_v2::printText(void) { case 6: ptr++; - extraCmd = *ptr++; + colCmd = *ptr++; colId = -1; - if (extraCmd & 0x80) { + if (colCmd & 0x80) { colId = (int16)READ_LE_UINT16(ptr); ptr += 2; } - if (extraCmd & 0x40) { + if (colCmd & 0x40) { rectLeft = destX + (int16)READ_LE_UINT16(ptr); rectRight = destX + (int16)READ_LE_UINT16(ptr + 2); rectTop = destY + (int16)READ_LE_UINT16(ptr + 4); @@ -318,7 +443,7 @@ void Draw_v2::printText(void) { case 7: ptr++; - extraCmd = 0; + colCmd = 0; break; case 8: @@ -332,61 +457,61 @@ void Draw_v2::printText(void) { break; case 10: - // loc_12C93 - str[0] = (char)255; - WRITE_LE_UINT16((uint16*)(str+1), ((char *) ptr) - _vm->_game->_totTextData->dataPtr); + str[0] = (char) 255; + WRITE_LE_UINT16((uint16 *) (str + 1), + ((char *) ptr) - _vm->_game->_totTextData->dataPtr); str[3] = 0; ptr++; - i = *ptr++; - for (i = *ptr++; i > 0; i--) { + for (int i = *ptr++; i > 0; i--) { mask[strPos++] = maskChar; ptr += 2; } break; default: - str[strPos] = cmd; + str[strPos] = (char) cmd; case 32: mask[strPos++] = maskChar; ptr++; break; case 186: - cmd = ptr2[17] & 0x7f; + cmd = ptrEnd[17] & 0x7F; if (cmd == 0) { - val = READ_LE_UINT16(ptr2 + 18) * 4; + val = READ_LE_UINT16(ptrEnd + 18) * 4; sprintf(buf, "%d", VAR_OFFSET(val)); } else if (cmd == 1) { - val = READ_LE_UINT16(ptr2 + 18) * 4; + val = READ_LE_UINT16(ptrEnd + 18) * 4; strcpy(buf, GET_VARO_STR(val)); } else { - val = READ_LE_UINT16(ptr2 + 18) * 4; + val = READ_LE_UINT16(ptrEnd + 18) * 4; sprintf(buf, "%d", VAR_OFFSET(val)); if (buf[0] == '-') { - while (strlen(buf) - 1 < (uint32)ptr2[17]) { + while (strlen(buf) - 1 < (uint32)ptrEnd[17]) { _vm->_util->insertStr("0", buf, 1); } } else { - while (strlen(buf) - 1 < (uint32)ptr2[17]) { + while (strlen(buf) - 1 < (uint32)ptrEnd[17]) { _vm->_util->insertStr("0", buf, 0); } } if (_vm->_global->_language == 2) - _vm->_util->insertStr(".", buf, strlen(buf) + 1 - ptr2[17]); + _vm->_util->insertStr(".", buf, strlen(buf) + 1 - ptrEnd[17]); else - _vm->_util->insertStr(",", buf, strlen(buf) + 1 - ptr2[17]); + _vm->_util->insertStr(",", buf, strlen(buf) + 1 - ptrEnd[17]); } memcpy(str + strPos, buf, strlen(buf)); memset(mask, maskChar, strlen(buf)); - if (ptr2[17] & 0x80) { + if (ptrEnd[17] & 0x80) { strPos2 = strPos + strlen(buf); strPos++; - ptr2 += 23; + ptrEnd += 23; ptr++; } else { strPos += strlen(buf); if (ptr[1] != ' ') { - if ((ptr[1] == 2) && (((int16)READ_LE_UINT16(ptr + 4)) == _destSpriteY)) { + if ((ptr[1] == 2) && + (((int16)READ_LE_UINT16(ptr + 4)) == _destSpriteY)) { ptr += 5; str[strPos] = ' '; mask[strPos++] = maskChar; @@ -396,10 +521,11 @@ void Draw_v2::printText(void) { mask[strPos++] = maskChar; while (ptr[1] == ' ') ptr++; - if ((ptr[1] == 2) && (((int16)READ_LE_UINT16(ptr + 4)) == _destSpriteY)) + if ((ptr[1] == 2) && + (((int16)READ_LE_UINT16(ptr + 4)) == _destSpriteY)) ptr += 5; } - ptr2 += 23; + ptrEnd += 23; ptr++; } break; @@ -407,7 +533,7 @@ void Draw_v2::printText(void) { } _renderFlags = savedFlags; - if (!(_renderFlags & 4)) + if (!(_renderFlags & RENDERFLAG_COLLISIONS)) return; _vm->_game->checkCollisions(0, 0, 0, 0); @@ -416,8 +542,6 @@ void Draw_v2::printText(void) { (*_vm->_scenery->_pCaptureCounter)--; _vm->_game->capturePop(1); } - - return; } void Draw_v2::spriteOperation(int16 operation) { @@ -426,35 +550,19 @@ void Draw_v2::spriteOperation(int16 operation) { Game::TotResItem *itemPtr; int32 offset; int16 len; - int16 i; - int16 x; - int16 y; - Video::SurfaceDesc *sourceSurf; - Video::SurfaceDesc *destSurf; + int16 x, y; + SurfaceDesc *sourceSurf, *destSurf; bool deltaVeto; int16 left; int16 ratio; - int16 spriteLeft; - int16 spriteTop; - int16 spriteRight; - int16 spriteBottom; - int16 destSpriteX; - int16 destSpriteY; - int16 destSurface; - int16 sourceSurface; -// .--- - int8 word_2F2D2 = -1; -// '--- - - if (operation & 0x10) { - deltaVeto = true; - operation &= 0x0F; - } else - deltaVeto = false; + // Some handle, but always assigned to -1 in Game::loadTotFile() + int16 word_2F2D2 = -1; + + deltaVeto = (bool) (operation & 0x10); + operation &= 0x0F; if (_sourceSurface >= 100) _sourceSurface -= 80; - if (_destSurface >= 100) _destSurface -= 80; @@ -467,63 +575,44 @@ void Draw_v2::spriteOperation(int16 operation) { if (_destSurface == 21) { _destSpriteX += _backDeltaX; _destSpriteY += _backDeltaY; - if (operation == DRAW_DRAWLINE || - (operation >= DRAW_DRAWBAR - && operation <= DRAW_FILLRECTABS)) { + if ((operation == DRAW_DRAWLINE) || + ((operation >= DRAW_DRAWBAR) && + (operation <= DRAW_FILLRECTABS))) { _spriteRight += _backDeltaX; _spriteBottom += _backDeltaY; } } } - spriteLeft = _spriteLeft; - spriteTop = _spriteTop; - spriteRight = _spriteRight; - spriteBottom = _spriteLeft; - destSpriteX = _destSpriteX; - destSpriteY = _destSpriteY; - destSurface = _destSurface; - sourceSurface = _sourceSurface; - -// warning("GOB2 Stub! _off_2E51B"); - if (_off_2E51B != 0) { - if ((_frontSurface->height <= _destSpriteY) && - ((_destSurface == 20) || (_destSurface == 21))) { - _destSpriteY -= _frontSurface->height; - if (operation == DRAW_DRAWLINE || - (operation >= DRAW_DRAWBAR - && operation <= DRAW_FILLRECTABS)) { - _spriteBottom -= _frontSurface->height; - } - if (_destSurface == 21) - invalidateRect(0, _frontSurface->height, _vm->_video->_surfWidth - 1, - _frontSurface->height + _off_2E51B->height - 1); - destSurface += 4; - } - if ((_frontSurface->height <= _spriteTop) && (operation == DRAW_BLITSURF) - && ((_destSurface == 20) || (_destSurface == 21))) { - _spriteTop -= _frontSurface->height; - _sourceSurface += 4; - } - } + int16 spriteLeft = _spriteLeft; + int16 spriteTop = _spriteTop; + int16 spriteRight = _spriteRight; + int16 spriteBottom = _spriteLeft; + int16 destSpriteX = _destSpriteX; + int16 destSpriteY = _destSpriteY; + int16 destSurface = _destSurface; + int16 sourceSurface = _sourceSurface; adjustCoords(0, &_destSpriteX, &_destSpriteY); - if ((operation != DRAW_LOADSPRITE) && (_word_2E8E2 != 2)) { + if ((operation != DRAW_LOADSPRITE) && (_needAdjust != 2)) { adjustCoords(0, &_spriteRight, &_spriteBottom); adjustCoords(0, &_spriteLeft, &_spriteTop); - if (operation == DRAW_DRAWLETTER) + + if (operation == DRAW_DRAWLINE) { + if ((_spriteRight == _destSpriteX) || (_spriteBottom == _destSpriteY)) { + operation = DRAW_FILLRECTABS; + _backColor = _frontColor; + } + } else if (operation == DRAW_DRAWLETTER) operation = DRAW_BLITSURF; - if ((operation == DRAW_DRAWLINE) && - ((_spriteRight == _destSpriteX) || (_spriteBottom == _destSpriteY))) { - operation = DRAW_FILLRECTABS; - _backColor = _frontColor; - } + if (operation == DRAW_DRAWLINE) { if (_spriteBottom < _destSpriteY) { SWAP(_spriteBottom, _destSpriteY); SWAP(_spriteRight, _destSpriteX); } - } else if ((operation == DRAW_LOADSPRITE) || (operation > DRAW_PRINTTEXT)) { + } else if ((operation == DRAW_LOADSPRITE) || + (operation > DRAW_PRINTTEXT)) { if (_spriteBottom < _destSpriteY) SWAP(_spriteBottom, _destSpriteY); if (_spriteRight < _destSpriteX) @@ -539,7 +628,7 @@ void Draw_v2::spriteOperation(int16 operation) { switch (operation) { case DRAW_BLITSURF: case DRAW_DRAWLETTER: - if ((sourceSurf == 0) || (destSurf == 0)) + if (!sourceSurf || !destSurf) break; _vm->_video->drawSprite(_spritesArray[_sourceSurface], @@ -551,17 +640,17 @@ void Draw_v2::spriteOperation(int16 operation) { if (_destSurface == 21) { invalidateRect(_destSpriteX, _destSpriteY, - _destSpriteX + _spriteRight - 1, - _destSpriteY + _spriteBottom - 1); + _destSpriteX + _spriteRight - 1, + _destSpriteY + _spriteBottom - 1); } break; case DRAW_PUTPIXEL: - _vm->_video->putPixel(_destSpriteX, _destSpriteY, - _frontColor, _spritesArray[_destSurface]); + _vm->_video->putPixel(_destSpriteX, _destSpriteY, _frontColor, + _spritesArray[_destSurface]); if (_destSurface == 21) { invalidateRect(_destSpriteX, _destSpriteY, - _destSpriteX, _destSpriteY); + _destSpriteX, _destSpriteY); } break; @@ -572,8 +661,8 @@ void Draw_v2::spriteOperation(int16 operation) { if (_destSurface == 21) { invalidateRect(_destSpriteX, _destSpriteY, - _destSpriteX + _spriteRight - 1, - _destSpriteY + _spriteBottom - 1); + _destSpriteX + _spriteRight - 1, + _destSpriteY + _spriteBottom - 1); } break; @@ -584,7 +673,7 @@ void Draw_v2::spriteOperation(int16 operation) { if (_destSurface == 21) { invalidateRect(_destSpriteX, _destSpriteY, - _spriteRight, _spriteBottom); + _spriteRight, _spriteBottom); } break; @@ -592,9 +681,10 @@ void Draw_v2::spriteOperation(int16 operation) { _vm->_video->drawCircle(_spritesArray[_destSurface], _destSpriteX, _destSpriteY, _spriteRight, _frontColor); if (_destSurface == 21) { - invalidateRect(_destSpriteX - _spriteRight, _destSpriteY - _spriteBottom, // !! - _destSpriteX + _spriteRight, - _destSpriteY + _spriteBottom); + invalidateRect(_destSpriteX - _spriteRight, + _destSpriteY - _spriteBottom, + _destSpriteX + _spriteRight, + _destSpriteY + _spriteBottom); } break; @@ -602,17 +692,14 @@ void Draw_v2::spriteOperation(int16 operation) { id = _spriteLeft; if (id >= 30000) { dataBuf = - _vm->_game->loadExtData(id, &_spriteRight, - &_spriteBottom); - _vm->_video->drawPackedSprite((byte *)dataBuf, _spriteRight, - _spriteBottom, _destSpriteX, - _destSpriteY, _transparency, - _spritesArray[_destSurface]); + _vm->_game->loadExtData(id, &_spriteRight, &_spriteBottom); + _vm->_video->drawPackedSprite((byte *) dataBuf, + _spriteRight, _spriteBottom, _destSpriteX, _destSpriteY, + _transparency, _spritesArray[_destSurface]); if (_destSurface == 21) { - invalidateRect(_destSpriteX, - _destSpriteY, - _destSpriteX + _spriteRight - 1, - _destSpriteY + _spriteBottom - 1); + invalidateRect(_destSpriteX, _destSpriteY, + _destSpriteX + _spriteRight - 1, + _destSpriteY + _spriteBottom - 1); } delete[] dataBuf; break; @@ -621,49 +708,44 @@ void Draw_v2::spriteOperation(int16 operation) { itemPtr = &_vm->_game->_totResourceTable->items[id]; offset = itemPtr->offset; if (offset >= 0) { - dataBuf = - _vm->_game->_totResourceTable->dataPtr + - szGame_TotResTable + szGame_TotResItem * - _vm->_game->_totResourceTable->itemsCount + offset; + dataBuf = _vm->_game->_totResourceTable->dataPtr + + szGame_TotResTable + szGame_TotResItem * + _vm->_game->_totResourceTable->itemsCount + offset; } else { - dataBuf = - _vm->_game->_imFileData + - (int32)READ_LE_UINT32(&((int32 *)_vm->_game->_imFileData)[-offset - 1]); + dataBuf = _vm->_game->_imFileData + + (int32) READ_LE_UINT32(&((int32 *) _vm->_game->_imFileData)[-offset - 1]); } _spriteRight = itemPtr->width; _spriteBottom = itemPtr->height; - _vm->_video->drawPackedSprite((byte *)dataBuf, + _vm->_video->drawPackedSprite((byte *) dataBuf, _spriteRight, _spriteBottom, _destSpriteX, _destSpriteY, _transparency, _spritesArray[_destSurface]); if (_destSurface == 21) { invalidateRect(_destSpriteX, _destSpriteY, - _destSpriteX + _spriteRight - 1, - _destSpriteY + _spriteBottom - 1); + _destSpriteX + _spriteRight - 1, + _destSpriteY + _spriteBottom - 1); } break; case DRAW_PRINTTEXT: len = strlen(_textToPrint); left = _destSpriteX; + if ((_fontIndex >= 4) || (_fontToSprite[_fontIndex].sprite == -1)) { - if (_fonts[_fontIndex]->extraData == 0) { + + if (!_fonts[_fontIndex]->extraData) { if (((int8) _textToPrint[0]) == -1) { - if (_vm->_global->_languageWanted != _vm->_global->_language) { - warning("Your game version doesn't support the requested language, " - "using the first one available (%d)", - _vm->_global->_language); - _vm->_global->_languageWanted = _vm->_global->_language; - } + _vm->validateLanguage(); + dataBuf = _vm->_game->_totTextData->dataPtr + _textToPrint[1] + 1; len = *dataBuf++; - for (i = 0; i < len; i++) { + for (int i = 0; i < len; i++, dataBuf += 2) { _vm->_video->drawLetter(READ_LE_UINT16(dataBuf), _destSpriteX, _destSpriteY, _fonts[_fontIndex], _transparency, _frontColor, _backColor, _spritesArray[_destSurface]); - dataBuf += 2; } } else { drawString(_textToPrint, _destSpriteX, _destSpriteY, _frontColor, @@ -672,40 +754,25 @@ void Draw_v2::spriteOperation(int16 operation) { _destSpriteX += len * _fonts[_fontIndex]->itemWidth; } } else { - if (word_2F2D2 >= 0) { - for (i = 0; i < len; i++) { + for (int i = 0; i < len; i++) { + if ((word_2F2D2 < 0) || (_textToPrint[i] != ' ')) { _vm->_video->drawLetter(_textToPrint[i], _destSpriteX, _destSpriteY, _fonts[_fontIndex], _transparency, _frontColor, _backColor, _spritesArray[_destSurface]); _destSpriteX += *(((char*)_fonts[_fontIndex]->extraData) + (_textToPrint[i] - _fonts[_fontIndex]->startItem)); } - } else { // loc_DBE9 - warning("Untested, does that work?"); - // Does something different for each character depending on whether it's a space - // That *should* be it... - for (i = 0; i < len; i++) { - if (_textToPrint[i] == ' ') - _destSpriteX += _fonts[_fontIndex]->itemWidth; - else { - _vm->_video->drawLetter(_textToPrint[i], - _destSpriteX, _destSpriteY, - _fonts[_fontIndex], - _transparency, - _frontColor, _backColor, - _spritesArray[_destSurface]); - _destSpriteX += - *(((char*)_fonts[_fontIndex]->extraData) + (_textToPrint[i] - _fonts[_fontIndex]->startItem)); - } - } + else + _destSpriteX += _fonts[_fontIndex]->itemWidth; } } + } else { sourceSurf = _spritesArray[_fontToSprite[_fontIndex].sprite]; ratio = ((sourceSurf == _frontSurface) || (sourceSurf == _backSurface)) ? - 320 : sourceSurf->width; + 320 : sourceSurf->getWidth(); ratio /= _fontToSprite[_fontIndex].width; - for (i = 0; i < len; i++) { + for (int i = 0; i < len; i++) { y = ((_textToPrint[i] - _fontToSprite[_fontIndex].base) / ratio) * _fontToSprite[_fontIndex].height; x = ((_textToPrint[i] - _fontToSprite[_fontIndex].base) % ratio) @@ -721,13 +788,13 @@ void Draw_v2::spriteOperation(int16 operation) { if (_destSurface == 21) { invalidateRect(left, _destSpriteY, - _destSpriteX - 1, - _destSpriteY + _fonts[_fontIndex]->itemHeight - 1); + _destSpriteX - 1, + _destSpriteY + _fonts[_fontIndex]->itemHeight - 1); } break; case DRAW_DRAWBAR: - if (_word_2E8E2 != 2) { + if (_needAdjust != 2) { _vm->_video->fillRect(_spritesArray[_destSurface], _destSpriteX, _spriteBottom - 1, _spriteRight, _spriteBottom, _frontColor); @@ -762,7 +829,7 @@ void Draw_v2::spriteOperation(int16 operation) { } if (_destSurface == 21) { invalidateRect(_destSpriteX, _destSpriteY, - _spriteRight, _spriteBottom); + _spriteRight, _spriteBottom); } break; @@ -775,7 +842,7 @@ void Draw_v2::spriteOperation(int16 operation) { } if (_destSurface == 21) { invalidateRect(_destSpriteX, _destSpriteY, - _spriteRight, _spriteBottom); + _spriteRight, _spriteBottom); } break; @@ -786,7 +853,7 @@ void Draw_v2::spriteOperation(int16 operation) { if (_destSurface == 21) { invalidateRect(_destSpriteX, _destSpriteY, - _spriteRight, _spriteBottom); + _spriteRight, _spriteBottom); } break; } @@ -819,191 +886,4 @@ void Draw_v2::spriteOperation(int16 operation) { } } -void Draw_v2::blitCursor(void) { - if (_cursorIndex == -1) - return; - - _showCursor = (_showCursor & ~2) | ((_showCursor & 1) << 1); -} - -void Draw_v2::animateCursor(int16 cursor) { - int16 newX = 0; - int16 newY = 0; - Game::Collision *ptr; - int16 minX; - int16 minY; - int16 maxX; - int16 maxY; - int16 cursorIndex; - uint16 hotspotX = 0; - uint16 hotspotY = 0; - - _showCursor |= 1; - - // .-- _draw_animateCursorSUB1 --- - cursorIndex = cursor; - if (cursorIndex == -1) { - cursorIndex = 0; - for (ptr = _vm->_game->_collisionAreas; ptr->left != -1; ptr++) { - if ((ptr->flags & 0xF00) || (ptr->id & 0x4000)) - continue; - - if (ptr->left > _vm->_global->_inter_mouseX) - continue; - - if (ptr->right < _vm->_global->_inter_mouseX) - continue; - - if (ptr->top > _vm->_global->_inter_mouseY) - continue; - - if (ptr->bottom < _vm->_global->_inter_mouseY) - continue; - - if ((ptr->flags & 0xF000) == 0) { - if ((ptr->flags & 0xF) >= 3) { - cursorIndex = 3; - break; - } else if (((ptr->flags & 0xF0) != 0x10) && (cursorIndex == 0)) - cursorIndex = 1; - } else if (cursorIndex == 0) - cursorIndex = (ptr->flags >> 12) & 0xF; - } - if (_cursorAnimLow[cursorIndex] == -1) - cursorIndex = 1; - } - // '------ - - if (_cursorAnimLow[cursorIndex] != -1) { - // .-- _draw_animateCursorSUB2 --- - if (cursorIndex == _cursorIndex) { - if ((_cursorAnimDelays[_cursorIndex] != 0) && - ((_cursorTimeKey + (_cursorAnimDelays[_cursorIndex] * 10)) <= - _vm->_util->getTimeKey())) { - _cursorAnim++; - if ((_cursorAnimHigh[_cursorIndex] < _cursorAnim) || - (_cursorAnimLow[_cursorIndex] > _cursorAnim)) - _cursorAnim = _cursorAnimLow[_cursorIndex]; - _cursorTimeKey = _vm->_util->getTimeKey(); - } else { - if ((_noInvalidated != 0) && (_vm->_global->_inter_mouseX == _cursorX) && - (_vm->_global->_inter_mouseY == _cursorY)) { - _vm->_video->waitRetrace(_vm->_global->_videoMode); - return; - } - } - } else { - _cursorIndex = cursorIndex; - if (_cursorAnimDelays[cursorIndex] != 0) { - _cursorAnim = _cursorAnimLow[cursorIndex]; - _cursorTimeKey = _vm->_util->getTimeKey(); - } - } - - if (_cursorAnimDelays[_cursorIndex] != 0) { - if ((_cursorAnimHigh[_cursorIndex] < _cursorAnim) || - (_cursorAnimLow[_cursorIndex] > _cursorAnim)) - _cursorAnim = _cursorAnimLow[_cursorIndex]; - - cursorIndex = _cursorAnim; - } - // '------ - - newX = _vm->_global->_inter_mouseX; - newY = _vm->_global->_inter_mouseY; - if (_cursorXDeltaVar != -1) { - newX -= hotspotX = (uint16) VAR(_cursorIndex + _cursorXDeltaVar); - newY -= hotspotY = (uint16) VAR(_cursorIndex + _cursorYDeltaVar); - } - - minX = MIN(newX, _cursorX); - minY = MIN(newY, _cursorY); - maxX = MAX(_cursorX, newX) + _cursorWidth - 1; - maxY = MAX(_cursorY, newY) + _cursorHeight - 1; - - _vm->_video->clearSurf(_scummvmCursor); - _vm->_video->drawSprite(_cursorSprites, _scummvmCursor, cursorIndex * _cursorWidth, - 0, (cursorIndex * _cursorWidth) + _cursorWidth - 1, _cursorHeight - 1, 0, 0, 0); - CursorMan.replaceCursor(_scummvmCursor->vidPtr, _cursorWidth, _cursorHeight, - hotspotX, hotspotY, 0); - - if (_frontSurface != _backSurface) { - if (_noInvalidated == 0) { - int16 tmp = _cursorIndex; - _cursorIndex = -1; - blitInvalidated(); - _cursorIndex = tmp; - } else { - _showCursor = 3; - _vm->_video->waitRetrace(_vm->_global->_videoMode); - if (minY < 50) - _vm->_util->delay(5); - } - } - } else - blitCursor(); - - _showCursor &= ~1; - - _cursorX = newX; - _cursorY = newY; -} - -void Draw_v2::initScreen(void) { - _scrollOffsetX = 0; - _scrollOffsetY = 0; - - if (_word_2E51F != 0) { - _off_2E51B = new Video::SurfaceDesc; - memcpy(_off_2E51B, _frontSurface, sizeof(Video::SurfaceDesc)); - _off_2E51B->height = _vm->_global->_primaryHeight - _word_2E51F; - _frontSurface->height -= _off_2E51B->height; - _frontSurface->vidPtr = - _off_2E51B->vidPtr + ((_off_2E51B->width * _off_2E51B->height) / 4); - - _off_2E517 = new Video::SurfaceDesc; - memcpy(_off_2E517, _off_2E51B, sizeof(Video::SurfaceDesc)); - _off_2E517->width = _vm->_global->_primaryWidth; - _off_2E517->vidPtr = _frontSurface->vidPtr + - ((_frontSurface->width * _frontSurface->height ) / 4); - } - initBigSprite(21, _vm->_video->_surfWidth, _vm->_video->_surfHeight, 0); - _backSurface = _spritesArray[21]; - _vm->_video->clearSurf(_backSurface); - - initBigSprite(23, 32, 16, 2); - _cursorSpritesBack = _spritesArray[23]; - _cursorSprites = _cursorSpritesBack; - _scummvmCursor = - _vm->_video->initSurfDesc(_vm->_global->_videoMode, 16, 16, SCUMMVM_CURSOR); - - _spritesArray[20] = _frontSurface; - _spritesArray[21] = _backSurface; - -/* if (_word_2E51F != 0) { - dword_2F92D = _off_2E51B; - dword_2F931 = _off_2E517; - }*/ -} - -void Draw_v2::closeScreen(void) { - freeSprite(23); - _cursorSprites = 0; - _cursorSpritesBack = 0; - _vm->_video->freeSurfDesc(_scummvmCursor); - _scummvmCursor = 0; - if (_off_2E51B != 0) { - memcpy(_frontSurface, _off_2E51B, sizeof(Video::SurfaceDesc)); - _frontSurface->width = _vm->_video->_surfWidth; - _frontSurface->height = _vm->_video->_surfHeight; - delete _off_2E51B; - delete _off_2E517; - _off_2E51B = 0; - _off_2E517 = 0; - } - if (_frontSurface != _backSurface) - freeSprite(21); - _spritesArray[21] = 0; -} - } // End of namespace Gob diff --git a/engines/gob/driver_vga.cpp b/engines/gob/driver_vga.cpp index b34ab14a66..0df7302d7d 100644 --- a/engines/gob/driver_vga.cpp +++ b/engines/gob/driver_vga.cpp @@ -23,105 +23,115 @@ #include "common/stdafx.h" #include "common/endian.h" - -#include "gob/driver_vga.h" #include "graphics/primitives.h" -#if defined (_MSC_VER) || defined (__WINS__) -#define STUB_FUNC printf("STUB:") -#else -#define STUB_FUNC printf("STUB: %s\n", __PRETTY_FUNCTION__) -#endif +#include "gob/driver_vga.h" namespace Gob { -void VGAVideoDriver::drawSprite(Video::SurfaceDesc *source, Video::SurfaceDesc *dest, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp) { - if (x >= 0 && x < dest->width && y >= 0 && y < dest->height) { - int16 width = (right - left) + 1; - int16 height = (bottom - top) + 1; - - byte *srcPos = source->vidPtr + (top * source->width) + left; - byte *destPos = dest->vidPtr + (y * dest->width) + x; - while (height--) { - if (transp) { - for (int16 i = 0; i < width; ++i) { - if (srcPos[i]) - destPos[i] = srcPos[i]; - } - } else { - for (int16 i = 0; i < width; ++i) - destPos[i] = srcPos[i]; - } +static void plotPixel(int x, int y, int color, void *data) { + SurfaceDesc *dest = (SurfaceDesc *)data; - srcPos += source->width; //width ? - destPos += dest->width; - } - } + if ((x >= 0) && (x < dest->getWidth()) && + (y >= 0) && (y < dest->getHeight())) + dest->getVidMem()[(y * dest->getWidth()) + x] = color; } -void VGAVideoDriver::fillRect(Video::SurfaceDesc *dest, int16 left, int16 top, int16 right, int16 bottom, byte color) { - if (left < dest->width && right < dest->width && top < dest->height && bottom < dest->height) { - byte *pos = dest->vidPtr + (top * dest->width) + left; - int16 width = (right - left) + 1; - int16 height = (bottom - top) + 1; - while (height--) { - for (int16 i = 0; i < width; ++i) { - pos[i] = color; - } +void VGAVideoDriver::putPixel(int16 x, int16 y, byte color, SurfaceDesc *dest) { + if ((x >= 0) && (x < dest->getWidth()) && + (y >= 0) && (y < dest->getHeight())) + dest->getVidMem()[(y * dest->getWidth()) + x] = color; +} - pos += dest->width; - } - } +void VGAVideoDriver::drawLine(SurfaceDesc *dest, int16 x0, int16 y0, int16 x1, + int16 y1, byte color) { + + Graphics::drawLine(x0, y0, x1, y1, color, &plotPixel, dest); } -void VGAVideoDriver::putPixel(int16 x, int16 y, byte color, Video::SurfaceDesc *dest) { - if (x >= 0 && x < dest->width && y >= 0 && y < dest->height) - dest->vidPtr[(y * dest->width) + x] = color; +void VGAVideoDriver::fillRect(SurfaceDesc *dest, int16 left, int16 top, + int16 right, int16 bottom, byte color) { + + if ((left >= dest->getWidth()) || (right >= dest->getWidth()) || + (top >= dest->getHeight()) || (bottom >= dest->getHeight())) + return; + + byte *pos = dest->getVidMem() + (top * dest->getWidth()) + left; + int16 width = (right - left) + 1; + int16 height = (bottom - top) + 1; + + while (height--) { + for (int16 i = 0; i < width; ++i) + pos[i] = color; + + pos += dest->getWidth(); + } } -void VGAVideoDriver::drawLetter(unsigned char item, int16 x, int16 y, Video::FontDesc *fontDesc, byte color1, byte color2, byte transp, Video::SurfaceDesc *dest) { +void VGAVideoDriver::drawLetter(unsigned char item, int16 x, int16 y, + Video::FontDesc *fontDesc, byte color1, byte color2, + byte transp, SurfaceDesc *dest) { byte *src, *dst; uint16 data; - int i, j; - src = (byte *)fontDesc->dataPtr + (item - fontDesc->startItem) * (fontDesc->itemSize & 0xff); - dst = dest->vidPtr + x + dest->width * y; + src = ((byte *) fontDesc->dataPtr) + + (item - fontDesc->startItem) * (fontDesc->itemSize & 0xFF); + dst = dest->getVidMem() + x + dest->getWidth() * y; - for (i = 0; i < fontDesc->itemHeight; i++) { + for (int i = 0; i < fontDesc->itemHeight; i++) { data = READ_BE_UINT16(src); src += 2; if (fontDesc->itemSize <= 8) src--; - for (j = 0; j < fontDesc->itemWidth; j++) { - if (data & 0x8000) { + for (int j = 0; j < fontDesc->itemWidth; j++) { + if (data & 0x8000) *dst = color2; - } else { - if (color1 == 0) - *dst = transp; - } + else if (color1 == 0) + *dst = transp; + dst++; data <<= 1; } - dst += dest->width - fontDesc->itemWidth; + dst += dest->getWidth() - fontDesc->itemWidth; } } -static void plotPixel(int x, int y, int color, void *data) { - Video::SurfaceDesc *dest = (Video::SurfaceDesc *)data; - if (x >= 0 && x < dest->width && y >= 0 && y < dest->height) - dest->vidPtr[(y * dest->width) + x] = color; -} +void VGAVideoDriver::drawSprite(SurfaceDesc *source, SurfaceDesc *dest, + int16 left, int16 top, int16 right, int16 bottom, + int16 x, int16 y, int16 transp) { -void VGAVideoDriver::drawLine(Video::SurfaceDesc *dest, int16 x0, int16 y0, int16 x1, int16 y1, byte color) { - Graphics::drawLine(x0, y0, x1, y1, color, &plotPixel, dest); + if ((x >= dest->getWidth()) || (x < 0) || + (y >= dest->getHeight()) || (y < 0)) + return; + + int16 width = (right - left) + 1; + int16 height = (bottom - top) + 1; + + byte *srcPos = source->getVidMem() + (top * source->getWidth()) + left; + byte *destPos = dest->getVidMem() + (y * dest->getWidth()) + x; + + while (height--) { + if (transp) { + for (int16 i = 0; i < width; ++i) { + if (srcPos[i]) + destPos[i] = srcPos[i]; + } + } else + for (int16 i = 0; i < width; ++i) + destPos[i] = srcPos[i]; + + srcPos += source->getWidth(); + destPos += dest->getWidth(); + } } -void VGAVideoDriver::drawPackedSprite(byte *sprBuf, int16 width, int16 height, int16 x, int16 y, byte transp, Video::SurfaceDesc *dest) { +void VGAVideoDriver::drawPackedSprite(byte *sprBuf, int16 width, int16 height, + int16 x, int16 y, byte transp, SurfaceDesc *dest) { int destRight = x + width; int destBottom = y + height; - byte* dst = dest->vidPtr + x + dest->width * y; + byte *dst = dest->getVidMem() + x + dest->getWidth() * y; int curx = x; int cury = y; @@ -130,6 +140,7 @@ void VGAVideoDriver::drawPackedSprite(byte *sprBuf, int16 width, int16 height, i uint8 val = *sprBuf++; unsigned int repeat = val & 7; val &= 0xF8; + if (!(val & 8)) { repeat <<= 8; repeat |= *sprBuf++; @@ -138,20 +149,21 @@ void VGAVideoDriver::drawPackedSprite(byte *sprBuf, int16 width, int16 height, i val >>= 4; for (unsigned int i = 0; i < repeat; ++i) { - if (curx < dest->width && cury < dest->height) + if (curx < dest->getWidth() && cury < dest->getHeight()) if (!transp || val) *dst = val; dst++; curx++; if (curx == destRight) { - dst += dest->width + x - curx; + dst += dest->getWidth() + x - curx; curx = x; cury++; if (cury == destBottom) return; } } + } } diff --git a/engines/gob/driver_vga.h b/engines/gob/driver_vga.h index de80b61c5f..54f577ffe8 100644 --- a/engines/gob/driver_vga.h +++ b/engines/gob/driver_vga.h @@ -20,6 +20,7 @@ * $Id$ * */ + #ifndef GOB_DRIVER_VGA_H #define GOB_DRIVER_VGA_H @@ -31,14 +32,21 @@ class VGAVideoDriver : public VideoDriver { public: VGAVideoDriver() {} virtual ~VGAVideoDriver() {} - void drawSprite(Video::SurfaceDesc *source, Video::SurfaceDesc *dest, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp); - void fillRect(Video::SurfaceDesc *dest, int16 left, int16 top, int16 right, int16 bottom, byte color); - void putPixel(int16 x, int16 y, byte color, Video::SurfaceDesc *dest); - void drawLetter(unsigned char item, int16 x, int16 y, Video::FontDesc *fontDesc, byte color1, byte color2, byte transp, Video::SurfaceDesc *dest); - void drawLine(Video::SurfaceDesc *dest, int16 x0, int16 y0, int16 x1, int16 y1, byte color); - void drawPackedSprite(byte *sprBuf, int16 width, int16 height, int16 x, int16 y, byte transp, Video::SurfaceDesc *dest); + + void putPixel(int16 x, int16 y, byte color, SurfaceDesc *dest); + void drawLine(SurfaceDesc *dest, int16 x0, int16 y0, + int16 x1, int16 y1, byte color); + void fillRect(SurfaceDesc *dest, int16 left, int16 top, + int16 right, int16 bottom, byte color); + void drawLetter(unsigned char item, int16 x, int16 y, + Video::FontDesc *fontDesc, byte color1, byte color2, + byte transp, SurfaceDesc *dest); + void drawSprite(SurfaceDesc *source, SurfaceDesc *dest, int16 left, + int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp); + void drawPackedSprite(byte *sprBuf, int16 width, int16 height, + int16 x, int16 y, byte transp, SurfaceDesc *dest); }; } -#endif +#endif // GOB_DRIVER_VGA_H diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp index 6122305f45..221ee46d30 100644 --- a/engines/gob/game.cpp +++ b/engines/gob/game.cpp @@ -25,27 +25,18 @@ #include "common/endian.h" #include "gob/gob.h" -#include "gob/global.h" #include "gob/game.h" -#include "gob/video.h" +#include "gob/global.h" +#include "gob/util.h" #include "gob/dataio.h" -#include "gob/pack.h" -#include "gob/scenery.h" #include "gob/inter.h" #include "gob/parse.h" #include "gob/draw.h" #include "gob/mult.h" -#include "gob/util.h" -#include "gob/goblin.h" -#include "gob/cdrom.h" #include "gob/music.h" -#include "gob/palanim.h" namespace Gob { -int16 Game::_captureCount = 0; -Common::Rect Game::_captureStack[20]; - Game::Game(GobEngine *vm) : _vm(vm) { _extTable = 0; _totFileData = 0; @@ -55,25 +46,18 @@ Game::Game(GobEngine *vm) : _vm(vm) { _collisionAreas = 0; _shouldPushColls = 0; + _captureCount = 0; + _foundTotLoc = false; _totTextData = 0; - // Collisions stack _collStackSize = 0; - int i; - for (i = 0; i < 5; i++) { + for (int i = 0; i < 5; i++) { _collStack[i] = 0; _collStackElemSizes[i] = 0; } - for (i = 0; i < 60; i++) { - _soundSamples[i] = 0; - _soundIds[i] = 0; - _soundTypes[i] = 0; - _soundFromExt[i] = 0; - _soundADL[i] = false; - } _infIns = 0; _infogrames = 0; @@ -100,7 +84,7 @@ Game::Game(GobEngine *vm) : _vm(vm) { _backupedCount = 0; _curBackupPos = 0; - for (i = 0; i < 5; i++) { + for (int i = 0; i < 5; i++) { _cursorXDeltaArray[i] = 0; _cursorYDeltaArray[i] = 0; _totTextDataArray[i] = 0; @@ -112,61 +96,24 @@ Game::Game(GobEngine *vm) : _vm(vm) { _variablesArray[i] = 0; _curTotFileArray[i][0] = 0; } - - _imdFile = 0; - _curImdFile[0] = 0; - _imdX = 0; - _imdY = 0; - _imdFrameDataSize = 0; - _imdVidBufferSize = 0; - _imdFrameData = 0; - _imdVidBuffer = 0; - - warning("GOB2 Stub! _byte_2FC82, _byte_2FC83, _word_2FC80"); - _byte_2FC82 = 0; - _byte_2FC83 = 0; - _word_2FC80 = 0; - - warning("GOB2 Stub! _byte_2FC9B, _dword_2F2B6"); - _byte_2FC9B = 0; - _dword_2F2B6 = 0; } Game::~Game() { - if (_imdFile) { - if (_imdFile->palette) - delete[] _imdFile->palette; - if (_imdFile->surfDesc && - (_imdFile->surfDesc != _vm->_draw->_spritesArray[20]) && - (_imdFile->surfDesc != _vm->_draw->_spritesArray[21])) - _vm->_video->freeSurfDesc(_imdFile->surfDesc); - if (_imdFile->framesPos) - delete[] _imdFile->framesPos; - if (_imdFile->frameCoords) - delete[] _imdFile->frameCoords; - delete _imdFile; - } - if (_imdFrameData) - delete[] _imdFrameData; - if (_imdVidBuffer) - delete[] _imdVidBuffer; - if (_word_2FC80) - delete[] _word_2FC80; - if (_infIns) - delete _infIns; + delete _infIns; for (int i = 0; i < 60; i++) - freeSoundSlot(i); + _soundSamples[i].free(); } -char *Game::loadExtData(int16 itemId, int16 *pResWidth, int16 *pResHeight, uint32 *dataSize) { +char *Game::loadExtData(int16 itemId, int16 *pResWidth, + int16 *pResHeight, uint32 *dataSize) { int16 commonHandle; int16 itemsCount; int32 offset; uint32 size; uint32 realSize; ExtItem *item; - char isPacked; + bool isPacked; int16 handle; int32 tableSize; char path[20]; @@ -185,62 +132,58 @@ char *Game::loadExtData(int16 itemId, int16 *pResWidth, int16 *pResHeight, uint3 offset = item->offset; size = item->size; - if (item->width & 0x8000) - isPacked = 1; - else - isPacked = 0; + isPacked = (bool) (item->width & 0x8000); if (pResWidth != 0) { - *pResWidth = item->width & 0x7fff; + *pResWidth = item->width & 0x7FFF; *pResHeight = item->height; - debugC(7, kDebugFileIO, "loadExtData(%d, %d, %d)", itemId, *pResWidth, *pResHeight); + debugC(7, kDebugFileIO, "loadExtData(%d, %d, %d)", + itemId, *pResWidth, *pResHeight); } debugC(7, kDebugFileIO, "loadExtData(%d, 0, 0)", itemId); if (item->height == 0) - size += (item->width & 0x7fff) << 16; + size += (item->width & 0x7FFF) << 16; debugC(7, kDebugFileIO, "size: %d off: %d", size, offset); - if (offset >= 0) { - handle = _extHandle; - } else { + if (offset < 0) { offset = -(offset + 1); tableSize = 0; - _vm->_dataio->closeData(_extHandle); + _vm->_dataIO->closeData(_extHandle); strcpy(path, "commun.ex1"); - path[strlen(path) - 1] = *(_totFileData + 0x3c) + '0'; - commonHandle = _vm->_dataio->openData(path); + path[strlen(path) - 1] = *(_totFileData + 0x3C) + '0'; + commonHandle = _vm->_dataIO->openData(path); handle = commonHandle; - } + } else + handle = _extHandle; debugC(7, kDebugFileIO, "off: %d size: %d", offset, tableSize); - _vm->_dataio->seekData(handle, offset + tableSize, SEEK_SET); + _vm->_dataIO->seekData(handle, offset + tableSize, SEEK_SET); realSize = size; - // CHECKME: is the below correct? if (isPacked) - dataBuf = new char[size]; + dataBuf = new char[size + 2]; else dataBuf = new char[size]; dataPtr = dataBuf; while (size > 32000) { // BUG: huge->far conversion. Need normalization? - _vm->_dataio->readData(handle, (char *)dataPtr, 32000); + _vm->_dataIO->readData(handle, (char *) dataPtr, 32000); size -= 32000; dataPtr += 32000; } - _vm->_dataio->readData(handle, (char *)dataPtr, size); + _vm->_dataIO->readData(handle, (char *) dataPtr, size); if (commonHandle != -1) { - _vm->_dataio->closeData(commonHandle); - _extHandle = _vm->_dataio->openData(_curExtFile); + _vm->_dataIO->closeData(commonHandle); + _extHandle = _vm->_dataIO->openData(_curExtFile); } - if (isPacked != 0) { + if (isPacked) { packedBuf = dataBuf; realSize = READ_LE_UINT32(packedBuf); dataBuf = new char[realSize]; - _vm->_pack->unpackData(packedBuf, dataBuf); + _vm->_dataIO->unpackData(packedBuf, dataBuf); delete[] packedBuf; } @@ -250,9 +193,7 @@ char *Game::loadExtData(int16 itemId, int16 *pResWidth, int16 *pResHeight, uint3 } void Game::freeCollision(int16 id) { - int16 i; - - for (i = 0; i < 250; i++) { + for (int i = 0; i < 250; i++) { if (_collisionAreas[i].id == id) _collisionAreas[i].left = -1; } @@ -273,11 +214,10 @@ void Game::capturePush(int16 left, int16 top, int16 width, int16 height) { _vm->_draw->_spriteBottom = height; right = left + width - 1; - left &= 0xfff0; - right |= 0xf; + left &= 0xFFF0; + right |= 0xF; - _vm->_draw->_spritesArray[30 + _captureCount] = - _vm->_video->initSurfDesc(_vm->_global->_videoMode, right - left + 1, height, 0); + _vm->_draw->initSpriteSurf(30 + _captureCount, right - left + 1, height, 0); _vm->_draw->_sourceSurface = 21; _vm->_draw->_destSurface = 30 + _captureCount; @@ -307,12 +247,11 @@ void Game::capturePop(char doDraw) { _vm->_draw->_transparency = 0; _vm->_draw->_sourceSurface = 30 + _captureCount; _vm->_draw->_destSurface = 21; - _vm->_draw->_spriteLeft = _vm->_draw->_destSpriteX & 0xf; + _vm->_draw->_spriteLeft = _vm->_draw->_destSpriteX & 0xF; _vm->_draw->_spriteTop = 0; _vm->_draw->spriteOperation(0); } - _vm->_video->freeSurfDesc(_vm->_draw->_spritesArray[30 + _captureCount]); - _vm->_draw->_spritesArray[30 + _captureCount] = 0; + _vm->_draw->freeSprite(30 + _captureCount); } char *Game::loadTotResource(int16 id, int16 *dataSize) { @@ -323,68 +262,39 @@ char *Game::loadTotResource(int16 id, int16 *dataSize) { offset = itemPtr->offset; if (dataSize) *dataSize = itemPtr->size; - if (offset >= 0) { + + if (offset < 0) { + offset = (-offset - 1) * 4; + return _imFileData + (int32) READ_LE_UINT32(_imFileData + offset); + } else return _totResourceTable->dataPtr + szGame_TotResTable + szGame_TotResItem * _totResourceTable->itemsCount + offset; - } else { - return (char *)(_imFileData + (int32)READ_LE_UINT32(&((int32 *)_imFileData)[-offset - 1])); - } -} - -void Game::loadSound(int16 slot, char *dataPtr, uint32 dataSize) { - Snd::SoundDesc *soundDesc; - byte *data = (byte *) dataPtr; - - soundDesc = new Snd::SoundDesc; - - _soundSamples[slot] = soundDesc; - - soundDesc->frequency = (data[4] << 8) + data[5]; - // Somehow, one sound in one CD version has a wrong size, leading to statics and crashes - soundDesc->size = MIN((uint32) ((data[1] << 16) + (data[2] << 8) + data[3]), dataSize - 6); - soundDesc->data = dataPtr + 6; - soundDesc->timerTicks = (int32)1193180 / (int32)soundDesc->frequency; - soundDesc->inClocks = (soundDesc->frequency * 10) / 182; - soundDesc->flag = 0; - } void Game::freeSoundSlot(int16 slot) { if (slot == -1) slot = _vm->_parse->parseValExpr(); - if ((slot < 0) || (slot >= 60) || (_soundSamples[slot] == 0)) + if ((slot < 0) || (slot >= 60) || _soundSamples[slot].empty()) return; - if (_soundADL[slot]) { + SoundDesc &sample = _soundSamples[slot]; + + if (sample.getType() == SOUND_ADL) if (_vm->_adlib && (_vm->_adlib->getIndex() == slot)) _vm->_adlib->stopPlay(); - if (_soundFromExt[slot] == 1) { - delete[] _soundSamples[slot]->data; - _soundFromExt[slot] = 0; - } - - delete _soundSamples[slot]; - } else { - char* data = _soundSamples[slot]->data; - - _vm->_snd->freeSoundDesc(_soundSamples[slot], false); - - if (_soundFromExt[slot] == 1) { - delete[] (data - 6); - _soundFromExt[slot] = 0; - } - } - _soundSamples[slot] = 0; + _vm->_snd->freeSample(sample); } -int16 Game::checkKeys(int16 *pMouseX, int16 *pMouseY, int16 *pButtons, char handleMouse) { +int16 Game::checkKeys(int16 *pMouseX, int16 *pMouseY, + int16 *pButtons, char handleMouse) { + _vm->_util->processInput(); if (_vm->_mult->_multData && (_vm->_global->_inter_variables != 0) && (VAR(58) != 0)) { - if (_vm->_mult->_multData->frameStart != (int)VAR(58) - 1) + if (_vm->_mult->_multData->frameStart != (int) VAR(58) - 1) _vm->_mult->_multData->frameStart++; else _vm->_mult->_multData->frameStart = 0; @@ -393,8 +303,8 @@ int16 Game::checkKeys(int16 *pMouseX, int16 *pMouseY, int16 *pButtons, char hand _vm->_mult->_multData->frameStart + VAR(57), 1, handleMouse); } - if (_vm->_inter->_soundEndTimeKey != 0 - && _vm->_util->getTimeKey() >= _vm->_inter->_soundEndTimeKey) { + if ((_vm->_inter->_soundEndTimeKey != 0) && + (_vm->_util->getTimeKey() >= _vm->_inter->_soundEndTimeKey)) { _vm->_snd->stopSound(_vm->_inter->_soundStopVal); _vm->_inter->_soundEndTimeKey = 0; } @@ -411,7 +321,7 @@ int16 Game::checkKeys(int16 *pMouseX, int16 *pMouseY, int16 *pButtons, char hand } int16 Game::adjustKey(int16 key) { - if (key <= 0x60 || key >= 0x7b) + if (key <= 0x60 || key >= 0x7B) return key; return key - 0x20; @@ -422,48 +332,47 @@ int32 Game::loadTotFile(char *path) { int32 size; size = -1; - handle = _vm->_dataio->openData(path); + handle = _vm->_dataIO->openData(path); if (handle >= 0) { - _vm->_dataio->closeData(handle); - size = _vm->_dataio->getDataSize(path); - _totFileData = _vm->_dataio->getData(path); - } else { + _vm->_dataIO->closeData(handle); + size = _vm->_dataIO->getDataSize(path); + _totFileData = _vm->_dataIO->getData(path); + } else _totFileData = 0; - } return size; } void Game::loadExtTable(void) { - int16 count, i; + int16 count; // Function is correct. [sev] - _extHandle = _vm->_dataio->openData(_curExtFile); + _extHandle = _vm->_dataIO->openData(_curExtFile); if (_extHandle < 0) return; - _vm->_dataio->readData(_extHandle, (char *)&count, 2); + _vm->_dataIO->readData(_extHandle, (char *) &count, 2); count = FROM_LE_16(count); - _vm->_dataio->seekData(_extHandle, 0, 0); + _vm->_dataIO->seekData(_extHandle, 0, 0); _extTable = new ExtTable; _extTable->items = 0; if (count) _extTable->items = new ExtItem[count]; - _vm->_dataio->readData(_extHandle, (char *)&_extTable->itemsCount, 2); + _vm->_dataIO->readData(_extHandle, (char *) &_extTable->itemsCount, 2); _extTable->itemsCount = FROM_LE_16(_extTable->itemsCount); - _vm->_dataio->readData(_extHandle, (char *)&_extTable->unknown, 1); + _vm->_dataIO->readData(_extHandle, (char *) &_extTable->unknown, 1); - for (i = 0; i < count; i++) { - _vm->_dataio->readData(_extHandle, (char *)&_extTable->items[i].offset, 4); + 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); + _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); + _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); + _vm->_dataIO->readData(_extHandle, (char *) &_extTable->items[i].height, 2); _extTable->items[i].height = FROM_LE_16(_extTable->items[i].height); } } @@ -472,24 +381,22 @@ void Game::loadImFile(void) { char path[20]; int16 handle; - if (_totFileData[0x3d] != 0 && _totFileData[0x3b] == 0) + if ((_totFileData[0x3D] != 0) && (_totFileData[0x3B] == 0)) return; strcpy(path, "commun.im1"); - if (_totFileData[0x3b] != 0) - path[strlen(path) - 1] = '0' + _totFileData[0x3b]; + if (_totFileData[0x3B] != 0) + path[strlen(path) - 1] = '0' + _totFileData[0x3B]; - handle = _vm->_dataio->openData(path); + handle = _vm->_dataIO->openData(path); if (handle < 0) return; - _vm->_dataio->closeData(handle); - _imFileData = _vm->_dataio->getData(path); + _vm->_dataIO->closeData(handle); + _imFileData = _vm->_dataIO->getData(path); } void Game::start(void) { - int i; - _collisionAreas = new Collision[250]; memset(_collisionAreas, 0, 250 * sizeof(Collision)); @@ -499,12 +406,9 @@ void Game::start(void) { delete[] _collisionAreas; _vm->_draw->closeScreen(); - _vm->_draw->_spritesArray[20] = 0; - for (i = 0; i < 50; i++) { - _vm->_video->freeSurfDesc(_vm->_draw->_spritesArray[i]); - _vm->_draw->_spritesArray[i] = 0; - } - _vm->_video->freeSurfDesc(_vm->_draw->_scummvmCursor); + for (int i = 0; i < SPRITES_COUNT; i++) + _vm->_draw->freeSprite(i); + _vm->_draw->_scummvmCursor = 0; } // flagbits: 0 = freeInterVariables, 1 = skipPlay @@ -514,8 +418,8 @@ void Game::totSub(int8 flags, char *newTotFile) { if (_backupedCount >= 5) return; - _cursorXDeltaArray[_backupedCount] = _vm->_draw->_cursorXDeltaVar; - _cursorYDeltaArray[_backupedCount] = _vm->_draw->_cursorYDeltaVar; + _cursorXDeltaArray[_backupedCount] = _vm->_draw->_cursorHotspotXVar; + _cursorYDeltaArray[_backupedCount] = _vm->_draw->_cursorHotspotYVar; _totTextDataArray[_backupedCount] = _totTextData; _totFileDataArray[_backupedCount] = _totFileData; _totResourceTableArray[_backupedCount] = _totResourceTable; @@ -564,8 +468,8 @@ void Game::totSub(int8 flags, char *newTotFile) { _backupedCount--; _curBackupPos = curBackupPos; - _vm->_draw->_cursorXDeltaVar = _cursorXDeltaArray[_backupedCount]; - _vm->_draw->_cursorYDeltaVar = _cursorYDeltaArray[_backupedCount]; + _vm->_draw->_cursorHotspotXVar = _cursorXDeltaArray[_backupedCount]; + _vm->_draw->_cursorHotspotYVar = _cursorYDeltaArray[_backupedCount]; _totTextData = _totTextDataArray[_backupedCount]; _totFileData = _totFileDataArray[_backupedCount]; _totResourceTable = _totResourceTableArray[_backupedCount]; @@ -576,7 +480,7 @@ void Game::totSub(int8 flags, char *newTotFile) { _vm->_global->_inter_variablesSizes = _variablesSizesArray[_backupedCount]; strcpy(_curTotFile, _curTotFileArray[_backupedCount]); strcpy(_curExtFile, _curTotFile); - _curExtFile[strlen(_curExtFile)-4] = '\0'; + _curExtFile[strlen(_curExtFile) - 4] = '\0'; strcat(_curExtFile, ".EXT"); } @@ -590,8 +494,8 @@ void Game::switchTotSub(int16 index, int16 skipPlay) { curBackupPos = _curBackupPos; backupedCount = _backupedCount; if (_curBackupPos == _backupedCount) { - _cursorXDeltaArray[_backupedCount] = _vm->_draw->_cursorXDeltaVar; - _cursorYDeltaArray[_backupedCount] = _vm->_draw->_cursorYDeltaVar; + _cursorXDeltaArray[_backupedCount] = _vm->_draw->_cursorHotspotXVar; + _cursorYDeltaArray[_backupedCount] = _vm->_draw->_cursorHotspotYVar; _totTextDataArray[_backupedCount] = _totTextData; _totFileDataArray[_backupedCount] = _totFileData; _totResourceTableArray[_backupedCount] = _totResourceTable; @@ -607,8 +511,8 @@ void Game::switchTotSub(int16 index, int16 skipPlay) { if (index >= 0) _curBackupPos--; - _vm->_draw->_cursorXDeltaVar = _cursorXDeltaArray[_curBackupPos]; - _vm->_draw->_cursorYDeltaVar = _cursorYDeltaArray[_curBackupPos]; + _vm->_draw->_cursorHotspotXVar = _cursorXDeltaArray[_curBackupPos]; + _vm->_draw->_cursorHotspotYVar = _cursorYDeltaArray[_curBackupPos]; _totTextData = _totTextDataArray[_curBackupPos]; _totFileData = _totFileDataArray[_curBackupPos]; _totResourceTable = _totResourceTableArray[_curBackupPos]; @@ -619,7 +523,7 @@ void Game::switchTotSub(int16 index, int16 skipPlay) { _vm->_global->_inter_variablesSizes = _variablesSizesArray[_curBackupPos]; strcpy(_curTotFile, _curTotFileArray[_curBackupPos]); strcpy(_curExtFile, _curTotFile); - _curExtFile[strlen(_curExtFile)-4] = '\0'; + _curExtFile[strlen(_curExtFile) - 4] = '\0'; strcat(_curExtFile, ".EXT"); if (_vm->_inter->_terminate != 0) @@ -635,8 +539,8 @@ void Game::switchTotSub(int16 index, int16 skipPlay) { _curBackupPos = curBackupPos; _backupedCount = backupedCount; - _vm->_draw->_cursorXDeltaVar = _cursorXDeltaArray[_curBackupPos]; - _vm->_draw->_cursorYDeltaVar = _cursorYDeltaArray[_curBackupPos]; + _vm->_draw->_cursorHotspotXVar = _cursorXDeltaArray[_curBackupPos]; + _vm->_draw->_cursorHotspotYVar = _cursorYDeltaArray[_curBackupPos]; _totTextData = _totTextDataArray[_curBackupPos]; _totFileData = _totFileDataArray[_curBackupPos]; _totResourceTable = _totResourceTableArray[_curBackupPos]; @@ -647,7 +551,7 @@ void Game::switchTotSub(int16 index, int16 skipPlay) { _vm->_global->_inter_variablesSizes = _variablesSizesArray[_curBackupPos]; strcpy(_curTotFile, _curTotFileArray[_curBackupPos]); strcpy(_curExtFile, _curTotFile); - _curExtFile[strlen(_curExtFile)-4] = '\0'; + _curExtFile[strlen(_curExtFile) - 4] = '\0'; strcat(_curExtFile, ".EXT"); } @@ -688,7 +592,7 @@ int16 Game::openLocTextFile(char *locTextFile, int language) { strcat(locTextFile, ".ang"); break; } - return _vm->_dataio->openData(locTextFile); + return _vm->_dataIO->openData(locTextFile); } char *Game::loadLocTexts(void) { @@ -712,11 +616,12 @@ char *Game::loadLocTexts(void) { } } } - debugC(1, kDebugFileIO, "Using language %d for %s", _vm->_global->_language, _curTotFile); + debugC(1, kDebugFileIO, "Using language %d for %s", + _vm->_global->_language, _curTotFile); if (handle >= 0) { - _vm->_dataio->closeData(handle); - return _vm->_dataio->getData(locTextFile); + _vm->_dataIO->closeData(handle); + return _vm->_dataIO->getData(locTextFile); } return 0; } @@ -730,20 +635,20 @@ void Game::setCollisions(void) { Collision *collArea; for (collArea = _collisionAreas; collArea->left != -1; collArea++) { - if (((collArea->id & 0xC000) != 0x8000) || (collArea->field_12 == 0)) + if (((collArea->id & 0xC000) != 0x8000) || (collArea->funcSub == 0)) continue; savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = _totFileData + collArea->field_12; + _vm->_global->_inter_execPtr = _totFileData + collArea->funcSub; left = _vm->_parse->parseValExpr(); top = _vm->_parse->parseValExpr(); width = _vm->_parse->parseValExpr(); height = _vm->_parse->parseValExpr(); - if ((_vm->_draw->_renderFlags & 8) && (left != -1)) { + if ((_vm->_draw->_renderFlags & RENDERFLAG_CAPTUREPOP) && (left != -1)) { left += _vm->_draw->_backDeltaX; top += _vm->_draw->_backDeltaY; } - if (_vm->_draw->_word_2E8E2 != 2) { + if (_vm->_draw->_needAdjust != 2) { _vm->_draw->adjustCoords(0, &left, &top); if ((collArea->flags & 0x0F) < 3) _vm->_draw->adjustCoords(2, &width, &height); @@ -801,937 +706,4 @@ void Game::collAreaSub(int16 index, int8 enter) { } } -Snd::SoundDesc *Game::loadSND(const char *path, int8 arg_4) { - Snd::SoundDesc *soundDesc; - uint32 dSize; - char *data; - char *dataPtr; - - soundDesc = new Snd::SoundDesc; - - dSize = _vm->_dataio->getDataSize(path) - 6; - data = _vm->_dataio->getData(path); - soundDesc->data = new char[dSize]; - soundDesc->flag = *data ? (*data & 0x7F) : 8; - dataPtr = data + 4; - - WRITE_LE_UINT16(dataPtr, READ_BE_UINT16(dataPtr)); - WRITE_LE_UINT32(data, - (READ_LE_UINT32(data) >> 24) + - ((READ_LE_UINT16(data) & 0xFF00) << 8) + - ((READ_LE_UINT16(data + 2) & 0xFF) >> 8)); - - soundDesc->size = MAX(dSize, READ_LE_UINT32(data)); - soundDesc->frequency = READ_LE_UINT16(dataPtr); - soundDesc->timerTicks = 1193180 / READ_LE_UINT16(dataPtr); - memcpy(soundDesc->data, data + 6, dSize - 6); - - if (arg_4 & 2) - arg_4 |= 1; - if ((soundDesc->frequency < 4700) && (arg_4 & 1)) - arg_4 &= 0xFE; - - if (arg_4 & 1) { - if ((_vm->_global->_soundFlags & BLASTER_FLAG) || (_vm->_global->_soundFlags & PROAUDIO_FLAG)) { - } - } - - return soundDesc; -} - -int8 Game::openImd(const char *path, int16 x, int16 y, int16 repeat, int16 flags) { - int i; - int j; - const char *src; - byte *vidMem; - Video::SurfaceDesc *surfDesc; - - if (path[0] != 0) { - if (_imdFile == 0) - _curImdFile[0] = 0; - - src = strrchr(path, '\\'); - src = src == 0 ? path : src+1; - - if (strcmp(_curImdFile, src) != 0) { - closeImd(); - _imdFile = loadImdFile(path, 0, 2); - if (_imdFile == 0) - return 0; - - _imdX = _imdFile->x; - _imdY = _imdFile->y; - strcpy(_curImdFile, src); - _imdFrameData = new byte[_imdFrameDataSize + 1000]; - _imdVidBuffer = new byte[_imdVidBufferSize + 1000]; - memset(_imdFrameData, 0, _imdFrameDataSize + 1000); - memset(_imdVidBuffer, 0, _imdVidBufferSize + 1000); - - if (_vm->_global->_videoMode == 0x14) { - _byte_2FC83 = (flags & 0x80) ? 1 : 0; - if (!(_imdFile->field_E & 0x100) || (_imdFile->field_E & 0x2000)) { - setImdXY(_imdFile, 0, 0); - _imdFile->surfDesc = - _vm->_video->initSurfDesc(0x13, _imdFile->width, _imdFile->height, 0); - } else { - if (_byte_2FC82 == 0) - _imdFile->surfDesc = _vm->_draw->_spritesArray[21]; - else - _imdFile->surfDesc = _vm->_draw->_spritesArray[20]; - if ((x != -1) || (y != -1)) { - _imdX = x != -1 ? x : _imdX; - _imdY = y != -1 ? y : _imdY; - setImdXY(_imdFile, _imdX, _imdY); - } - } - if (flags & 0x40) { - _imdX = x != -1 ? x : _imdX; - _imdY = y != -1 ? y : _imdY; - if ((_imdFile->surfDesc->vidMode & 0x7F) == 0x14) { - surfDesc = _vm->_video->initSurfDesc(0x13, _imdFile->width, _imdFile->height, 0); - _vm->_video->drawSprite(_vm->_draw->_spritesArray[21], surfDesc, _imdX, _imdY, - _imdX + _imdFile->width - 1, _imdY + _imdFile->height - 1, 0, 0, 0); - vidMem = _imdFile->surfDesc->vidPtr; - for (i = 0; i < _imdFile->height; i++) - for (j = 0; j < _imdFile->width; j++, vidMem++) { - *(vidMem) = *(surfDesc->vidPtr - + (j / 4) - + (surfDesc->width / 4 * i) - + (surfDesc->reserved2 * (j & 3))); - } - _vm->_video->freeSurfDesc(surfDesc); - } - } - } else { - if ((x != -1) || (y != -1)) { - _imdX = x != -1 ? x : _imdX; - _imdY = y != -1 ? y : _imdY; - setImdXY(_imdFile, _imdX, _imdY); - } - _byte_2FC83 = (flags & 0x80) ? 1 : 0; - if (_byte_2FC83 == 0) - _imdFile->surfDesc = _vm->_draw->_spritesArray[21]; - else - _imdFile->surfDesc = _vm->_draw->_spritesArray[20]; - } - } - } - - if (_imdFile == 0) - return 0; - - if (repeat == -1) { - closeImd(); - return 0; - } - - _imdX = x != -1 ? x : _imdX; - _imdY = y != -1 ? y : _imdY; - - WRITE_VAR(7, _imdFile->framesCount); - - return 1; -} - -void Game::closeImd(void) { - if (_imdFile == 0) - return; - - if ((_imdFile->surfDesc != _vm->_draw->_spritesArray[20]) && - (_imdFile->surfDesc != _vm->_draw->_spritesArray[21])) - _vm->_video->freeSurfDesc(_imdFile->surfDesc); - - finishImd(_imdFile); - - delete[] _imdFrameData; - delete[] _imdVidBuffer; - _imdFrameData = 0; - _imdVidBuffer = 0; - - _imdFile = 0; -} - -void Game::finishImd(Game::Imd *imdPtr) { - if (imdPtr == 0) - return; - -/* - if (dword_31345 != 0) { - _vm->_sound->stopSound(0); - dword_31345 = 0; - delete off_31461; - byte_31344 = 0; - } -*/ - - _vm->_dataio->closeData(imdPtr->fileHandle); - - if (imdPtr->frameCoords != 0) - delete[] imdPtr->frameCoords; - if (imdPtr->palette != 0) - delete[] imdPtr->palette; - if (imdPtr->framesPos != 0) - delete[] imdPtr->framesPos; - - delete imdPtr; - imdPtr = 0; -} - -// flagsBit: 0 = read and set palette -// 1 = read palette -Game::Imd *Game::loadImdFile(const char *path, Video::SurfaceDesc *surfDesc, int8 flags) { - int i; - Imd *imdPtr; - int16 handle; - int16 setAllPalBak; - char buf[18]; - Video::Color *palBak; - - int32 byte_31449 = 0; - int32 byte_3144D = 0; - - buf[0] = 0; - strcpy(buf, path); - strcat(buf, ".IMD"); - - handle = _vm->_dataio->openData(buf); - - if (handle < 0) { - warning("Can't open IMD \"%s\"", buf); - return 0; - } - - imdPtr = new Imd; - memset(imdPtr, 0, sizeof(Imd)); - - imdPtr->palette = 0; - - _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); - _vm->_dataio->closeData(handle); - delete imdPtr; - return 0; - } - - imdPtr->surfDesc = surfDesc; - imdPtr->framesPos = 0; - imdPtr->firstFramePos = imdPtr->curFrame; - - if (flags & 3) { - imdPtr->palette = new Video::Color[256]; - _vm->_dataio->readData(handle, (char *) imdPtr->palette, 768); - } else { - _vm->_dataio->seekData(handle, 768, 1); - imdPtr->palette = 0; - } - if ((flags & 3) == 1) { - palBak = _vm->_global->_pPaletteDesc->vgaPal; - setAllPalBak = _vm->_global->_setAllPalette; - _vm->_global->_pPaletteDesc->vgaPal = imdPtr->palette; - _vm->_global->_setAllPalette = 1; - _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); - _vm->_global->_setAllPalette = setAllPalBak; - _vm->_global->_pPaletteDesc->vgaPal = palBak; - } - - if ((imdPtr->verMin & 0xFF) >= 3) { - _vm->_dataio->readData(handle, buf, 2); - imdPtr->stdX = READ_LE_UINT16(buf); - if (imdPtr->stdX > 1) { - warning("IMD ListI incorrect (%d)", imdPtr->stdX); - _vm->_dataio->closeData(handle); - delete 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); - } else - imdPtr->stdX = -1; - } else - imdPtr->stdX = -1; - - if ((imdPtr->verMin & 0xFF) >= 4) { - _vm->_dataio->readData(handle, buf, 4); - byte_31449 = READ_LE_UINT32(buf); - imdPtr->framesPos = byte_31449 == 0 ? 0 : new int32[imdPtr->framesCount]; - } else - imdPtr->framesPos = 0; - - if (imdPtr->verMin & 0x8000) { - _vm->_dataio->readData(handle, buf, 4); - byte_3144D = READ_LE_UINT32(buf); - } - - if (imdPtr->verMin & 0x4000) { - // loc_29C4F - warning("GOB2 Stub! loadImdFile, imdPtr->verMin & 0x4000"); - warning("Can't open IMD \"%s.IMD\"", path); - return 0; - // Sound stuff, I presume... - } - - if (imdPtr->verMin & 0x2000) { - _vm->_dataio->readData(handle, buf, 4); - imdPtr->frameDataSize = READ_LE_UINT16(buf); - imdPtr->vidBufferSize = READ_LE_UINT16(buf + 2); - } else { - imdPtr->frameDataSize = imdPtr->width * imdPtr->height + 1000; - imdPtr->vidBufferSize = imdPtr->width * imdPtr->height + 1000; - } - - 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->verMin & 0x8000) { - _vm->_dataio->seekData(handle, byte_3144D, 0); - 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); - } - } else - imdPtr->frameCoords = 0; - - _vm->_dataio->seekData(handle, imdPtr->firstFramePos, 0); - imdPtr->curFrame = 0; - imdPtr->fileHandle = handle; - imdPtr->filePos = imdPtr->firstFramePos; - _imdFrameDataSize = imdPtr->frameDataSize; - _imdVidBufferSize = imdPtr->vidBufferSize; - if (flags & 0x80) { - imdPtr->verMin |= 0x1000; - warning("GOB2 Stub! loadImdFile(), flags & 0x80"); - } - - return imdPtr; -} - -void Game::setImdXY(Game::Imd *imdPtr, int16 x, int16 y) { - int i; - - if (imdPtr->stdX != -1) { - imdPtr->stdX = imdPtr->stdX - imdPtr->x + x; - imdPtr->stdY = imdPtr->stdY - imdPtr->y + y; - } - - if (imdPtr->frameCoords != 0) { - 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 Game::playImd(int16 frame, int16 arg_2, int16 arg_4, int16 arg_6, int16 arg_8, int16 lastFrame) { - int16 var_1; - int16 var_4 = 0; - byte *vidMemBak; - Video::SurfaceDesc *surfDescBak; - Video::SurfaceDesc frontSurfBak; - - _vm->_draw->_showCursor = 0; - - int8 byte_31344 = 0; - - if ((frame < 0) || (frame > lastFrame)) - return; - - if ((frame == arg_8) || ((frame == lastFrame) && (arg_2 == 8))) { // loc_1C3F0 - var_1 = 1; - _vm->_draw->_applyPal = 0; - if (arg_2 >= 4) { - if (arg_4 != -1) - memcpy( ((char *) (_vm->_global->_pPaletteDesc->vgaPal)) + arg_4 * 3, - ((char *) (_imdFile->palette)) + arg_4 * 3, (arg_6 - arg_4 + 1) * 3); - else - memcpy((char *) _vm->_global->_pPaletteDesc->vgaPal, (char *) _imdFile->palette, 768); - } - } else - var_1 = 0; - - if ((var_1 == 1) && (arg_2 == 8) && (_byte_2FC83 != 0)) - _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); - - if (_imdFile->surfDesc->vidMode == 0x14) { - if ((_byte_2FC82 != 0) && (_word_2FC80 == _vm->_draw->_spritesArray[20]->vidPtr)) { - vidMemBak = _vm->_draw->_spritesArray[20]->vidPtr; - _vm->_draw->_spritesArray[20]->vidPtr = _vm->_draw->_spritesArray[21]->vidPtr; - var_4 = viewImd(_imdFile, frame); - _vm->_draw->_spritesArray[20]->vidPtr = vidMemBak; - } else - var_4 = viewImd(_imdFile, frame); - if (_byte_2FC82 == 0) { - if ((_imdFile->frameCoords == 0) || (_imdFile->frameCoords[frame].left == -1)) - _vm->_draw->invalidateRect(_imdX, _imdY, - _imdX + _imdFile->width - 1, _imdY + _imdFile->height - 1); - else - _vm->_draw->invalidateRect(_imdFile->frameCoords[frame].left, - _imdFile->frameCoords[frame].top, _imdFile->frameCoords[frame].right, - _imdFile->frameCoords[frame].bottom); - } - } else { - if ((_imdFile->field_E & 0x100) && (_vm->_global->_videoMode == 0x14) && - (_byte_2FC82 != 0) && (sub_2C825(_imdFile) & 0x8000) && (_byte_2FC83 == 0)) { - surfDescBak = _imdFile->surfDesc; - if (_word_2FC80 == _vm->_draw->_spritesArray[20]->vidPtr) - _imdFile->surfDesc = _vm->_draw->_spritesArray[21]; - else - _imdFile->surfDesc = _vm->_draw->_spritesArray[20]; - setImdXY(_imdFile, _imdX, _imdY); - var_4 = viewImd(_imdFile, frame); - _imdFile->surfDesc = surfDescBak; - setImdXY(_imdFile, 0, 0); - } else { - var_4 = viewImd(_imdFile, frame); - if (!(var_4 & 0x800)) { - if (_byte_2FC83 == 0) { - if (_vm->_global->_videoMode == 0x14) { - if (_byte_2FC82 == 0) { - memcpy((char *) &frontSurfBak, (char *) &_vm->_draw->_frontSurface, - sizeof(Video::SurfaceDesc)); - memcpy((char *) &_vm->_draw->_frontSurface, (char *) &_vm->_draw->_spritesArray[21], - sizeof(Video::SurfaceDesc)); - imdDrawFrame(_imdFile, frame, _imdX, _imdY); - memcpy((char *) &_vm->_draw->_frontSurface, (char *) &frontSurfBak, - sizeof(Video::SurfaceDesc)); - if ((_imdFile->frameCoords == 0) || (_imdFile->frameCoords[frame].left == -1)) - _vm->_draw->invalidateRect(_imdX, _imdY, _imdX + _imdFile->width - 1, - _imdY + _imdFile->height - 1); - else - _vm->_draw->invalidateRect(_imdFile->frameCoords[frame].left, - _imdFile->frameCoords[frame].top, _imdFile->frameCoords[frame].right, - _imdFile->frameCoords[frame].bottom); - } else { - if (_word_2FC80 == _vm->_draw->_spritesArray[20]->vidPtr) { // loc_1C68D - memcpy((char *) &frontSurfBak, (char *) &_vm->_draw->_frontSurface, - sizeof(Video::SurfaceDesc)); - memcpy((char *) &_vm->_draw->_frontSurface, (char *) &_vm->_draw->_spritesArray[21], - sizeof(Video::SurfaceDesc)); - imdDrawFrame(_imdFile, frame, _imdX, _imdY); - memcpy((char *) &_vm->_draw->_frontSurface, (char *) &frontSurfBak, - sizeof(Video::SurfaceDesc)); - } else - imdDrawFrame(_imdFile, frame, _imdX, _imdY); - } - } else { - if ((_imdFile->frameCoords == 0) || (_imdFile->frameCoords[frame].left == -1)) - _vm->_draw->invalidateRect(_imdX, _imdY, _imdX + _imdFile->width - 1, - _imdY + _imdFile->height - 1); - else - _vm->_draw->invalidateRect(_imdFile->frameCoords[frame].left, - _imdFile->frameCoords[frame].top, _imdFile->frameCoords[frame].right, - _imdFile->frameCoords[frame].bottom); - } - } else - if (_vm->_global->_videoMode == 0x14) - imdDrawFrame(_imdFile, frame, _imdX, _imdY); - } - } - } - - if ((var_1 != 0) && (arg_2 == 16)) { - if ((_vm->_draw->_spritesArray[20] != _vm->_draw->_spritesArray[21]) && (_byte_2FC83 == 0)) - _vm->_video->drawSprite(_vm->_draw->_spritesArray[21], - _vm->_draw->_spritesArray[20], 0, 0, - _vm->_draw->_spritesArray[21]->width - 1, - _vm->_draw->_spritesArray[21]->height - 1, 0, 0, 0); - _vm->_palanim->fade(_vm->_global->_pPaletteDesc, -2, 0); - _vm->_draw->_noInvalidated = 1; - } - if ((var_1 != 0) && (arg_2 == 8) && (_byte_2FC83 == 0)) - _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); - - if (!(var_4 & 0x800)) { - if (_vm->_draw->_cursorIndex == -1) { - if (_byte_2FC82 != 0) { - if (_word_2FC80 == _vm->_draw->_spritesArray[20]->vidPtr) - _word_2FC80 = _vm->_draw->_spritesArray[21]->vidPtr; - else - _word_2FC80 = _vm->_draw->_spritesArray[20]->vidPtr; - warning("GOB2 Stub! sub_1BC3A(_word_2FC80);"); - } else - _vm->_draw->blitInvalidated(); - } else - _vm->_draw->animateCursor(-1); - } - - if ((var_1 != 0) && ((arg_2 == 2) || (arg_2 == 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 (var_4 & 0x800) { - if (_dword_2F2B6 == 0) - _vm->_util->delay(30); - else { - _dword_2F2B6 -= 30; - if (_dword_2F2B6 < 0) - _dword_2F2B6 = 0; - } - } else - _vm->_util->waitEndFrame(); - } - _vm->_inter->animPalette(); -} - -int16 Game::viewImd(Game::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; - } - } - - _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! viewImd, 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 *) _imdFrameData, tmp + 2); - retVal |= *_imdFrameData; - if (imdPtr->surfDesc == 0) - continue; - if (imdPtr->surfDesc->vidMode != 0x14) - imdRenderFrame(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 Game::imdDrawFrame(Imd *imdPtr, int16 frame, int16 x, int16 y, - Video::SurfaceDesc *dest) { - if (!dest) - dest = _vm->_draw->_frontSurface; - - 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)) - _vm->_video->drawSprite(imdPtr->surfDesc, dest, - imdPtr->frameCoords[frame].left, imdPtr->frameCoords[frame].top, - imdPtr->frameCoords[frame].right, imdPtr->frameCoords[frame].bottom, - imdPtr->frameCoords[frame].left, imdPtr->frameCoords[frame].top, 1); - else if (imdPtr->stdX != -1) - _vm->_video->drawSprite(imdPtr->surfDesc, dest, - imdPtr->stdX, imdPtr->stdY, imdPtr->stdX + imdPtr->stdWidth - 1, - imdPtr->stdY + imdPtr->stdHeight - 1, x + imdPtr->stdX, - y + imdPtr->stdY, 1); - else - _vm->_video->drawSprite(imdPtr->surfDesc, dest, 0, 0, - imdPtr->width - 1, imdPtr->height - 1, x, y, 0); -} - -void Game::imdRenderFrame(Imd *imdPtr) { - int i; - int16 imdX; - int16 imdY; - int16 imdW; - int16 imdH; - int16 sW; - uint16 pixCount, pixWritten; - uint8 type; - byte *imdVidMem; - byte *imdVidMemBak; - byte *dataPtr = 0; - byte *srcPtr = 0; - byte *srcPtrBak = 0; - - dataPtr = (byte *) _imdFrameData; - imdX = imdPtr->x; - imdY = imdPtr->y; - imdW = imdPtr->width; - imdH = imdPtr->height; - sW = imdPtr->surfDesc->width; - imdVidMem = imdPtr->surfDesc->vidPtr + sW * imdY + imdX; - - type = *dataPtr++; - srcPtr = dataPtr; - - if (type & 0x10) { - type ^= 0x10; - dataPtr++; // => 0x3C8 |_ palette - dataPtr += 48; // => 0x3C9 | stuff - } - - srcPtr = dataPtr; - if (type & 0x80) { - srcPtr = (byte *) _imdVidBuffer; - type &= 0x7F; - if ((type == 2) && (imdW == sW)) { - imdFrameUncompressor(imdVidMem, dataPtr); - return; - } else - imdFrameUncompressor(srcPtr, dataPtr); - } - - if (type == 2) { - for (i = 0; i < imdH; i++) { - memcpy(imdVidMem, srcPtr, imdW); - srcPtr += imdW; - imdVidMem += sW; - } - } else if (type == 1) { - imdVidMemBak = imdVidMem; - for (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; - memcpy(imdVidMem, srcPtr, pixCount); - imdVidMem += pixCount; - srcPtr += pixCount; - } else { - pixCount = (pixCount + 1) % 256; - pixWritten += pixCount; - imdVidMem += pixCount; - } - } - 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) { - 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; - memcpy(imdVidMem, srcPtr, pixCount); - memcpy(imdVidMem + sW, srcPtr, pixCount); - imdVidMem += pixCount; - srcPtr += pixCount; - } else { - pixCount = (pixCount + 1) % 256; - pixWritten += pixCount; - imdVidMem += pixCount; - } - } - srcPtrBak += sW + sW; - srcPtr = srcPtrBak; - } - } -} - -void Game::imdFrameUncompressor(byte *dest, byte *src) { - int i; - byte buf[4370]; - int16 chunkLength; - int16 frameLength; - uint16 bufPos1; - uint16 bufPos2; - uint16 tmp; - uint8 chunkBitField; - uint8 chunkCount; - bool mode; - - 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) - } - memset(buf, 32, bufPos1); - chunkCount = 1; - chunkBitField = 0; - - while (frameLength > 0) { - chunkCount--; - if (chunkCount == 0) { - tmp = *src++; - chunkCount = 8; - chunkBitField = tmp; - } - if (chunkBitField % 2) { - chunkBitField >>= 1; - buf[bufPos1] = *src; - *dest++ = *src++; - bufPos1 = (bufPos1 + 1) % 4096; - frameLength--; - continue; - } - chunkBitField >>= 1; - - tmp = READ_LE_UINT16(src); - src += 2; - chunkLength = ((tmp & 0xF00) >> 8) + 3; - - if ((mode && ((chunkLength & 0xFF) == 0x12)) || (!mode && (chunkLength == 0))) - chunkLength = *src++ + 0x12; - - bufPos2 = (tmp & 0xFF) + ((tmp >> 4) & 0x0F00); - 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)) { - memcpy(dest, buf + bufPos2, chunkLength); - dest += chunkLength; - memmove(buf + bufPos1, buf + bufPos2, 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; - } - } -} - -void Game::playImd(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 + _imdFile->width - 1, - y + _imdFile->height - 1, 0); - - if (fade) - _vm->_palanim->fade(0, -2, 0); - - endFrame = frames > 0 ? frames : _imdFile->framesCount; - for (curFrame = 0; curFrame < endFrame; curFrame++) { - viewImd(_imdFile, curFrame); - imdDrawFrame(_imdFile, curFrame, x, y); - if (fade) { - _vm->_palanim->fade(_vm->_global->_pPaletteDesc, -2, 0); - fade = false; - } - _vm->_video->waitRetrace(_vm->_global->_videoMode); - if ((interruptible && (checkKeys(&mouseX, &mouseY, &buttons, 0) == 0x11B)) || - _vm->_quitRequested) { - _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 = _imdFile->framesCount + frames; - for (curFrame = _imdFile->framesCount - 1; curFrame >= endFrame; curFrame--) { - for (backFrame = 0; backFrame <= curFrame; backFrame++) - viewImd(_imdFile, backFrame); - imdDrawFrame(_imdFile, curFrame, x, y); - _vm->_video->waitRetrace(_vm->_global->_videoMode); - if ((interruptible && (checkKeys(&mouseX, &mouseY, &buttons, 0) == 0x11B)) || - _vm->_quitRequested) { - _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 Game::sub_2C825(Imd *imdPtr) { - warning("GOB2 Stub! sub_2C825()"); - return 0; -} - } // End of namespace Gob diff --git a/engines/gob/game.h b/engines/gob/game.h index 99001c1a36..0f916dbcc8 100644 --- a/engines/gob/game.h +++ b/engines/gob/game.h @@ -20,13 +20,13 @@ * $Id$ * */ + #ifndef GOB_GAME_H #define GOB_GAME_H #include "sound/mods/infogrames.h" + #include "gob/sound.h" -#include "gob/music.h" -#include "gob/video.h" namespace Gob { @@ -45,7 +45,7 @@ public: int16 key; uint16 funcEnter; uint16 funcLeave; - int16 field_12; // New in GOB2 + uint16 funcSub; }; #define szGame_TotResItem (4 + 2 + 2 + 2) @@ -69,7 +69,7 @@ public: struct ExtItem { int32 offset; // offset from the table end uint16 size; - int16 width; // width&0x7fff - width, width&0x8000 - pack flag + int16 width; // width & 0x7FFF: width, width & 0x8000: pack flag int16 height; // not zero }; @@ -100,37 +100,6 @@ public: char *ptr; }; - struct ImdCoord { - int16 left; - int16 top; - int16 right; - int16 bottom; - }; - - struct Imd { - int16 fileHandle; - int16 verMin; - int16 framesCount; - int16 x; - int16 y; - int16 width; - int16 height; - int16 field_E; - int16 curFrame; - Video::Color *palette; - Video::SurfaceDesc *surfDesc; - int32 *framesPos; - int32 firstFramePos; - int16 stdX; - int16 stdY; - int16 stdWidth; - int16 stdHeight; - int32 filePos; - ImdCoord *frameCoords; - int32 frameDataSize; - int32 vidBufferSize; - }; - #include "common/pack-end.h" // END STRUCT PACKING TotResTable *_totResourceTable; @@ -148,11 +117,7 @@ public: int16 _extHandle; - Snd::SoundDesc *_soundSamples[60]; - int16 _soundIds[60]; - int8 _soundTypes[60]; - char _soundFromExt[60]; - bool _soundADL[60]; + SoundDesc _soundSamples[60]; Audio::Infogrames::Instruments *_infIns; Audio::Infogrames *_infogrames; @@ -163,33 +128,6 @@ public: int32 _startTimeKey; int16 _mouseButtons; - // For totSub() - int8 _backupedCount; - int8 _curBackupPos; - int16 _cursorXDeltaArray[5]; - int16 _cursorYDeltaArray[5]; - TotTextTable *_totTextDataArray[5]; - char *_totFileDataArray[5]; - TotResTable *_totResourceTableArray[5]; - ExtTable *_extTableArray[5]; - int16 _extHandleArray[5]; - char *_imFileDataArray[5]; - char *_variablesArray[5]; - char _curTotFileArray[5][14]; - byte *_variablesSizesArray[5]; - - Imd *_imdFile; - char _curImdFile[15]; - int16 _imdX; - int16 _imdY; - int16 _imdFrameDataSize; - int16 _imdVidBufferSize; - byte *_imdFrameData; - byte *_imdVidBuffer; - int8 _byte_2FC82; - int8 _byte_2FC83; - byte *_word_2FC80; - Game(GobEngine *vm); virtual ~Game(); @@ -197,56 +135,33 @@ public: char *loadTotResource(int16 id, int16 *dataSize = 0); void capturePush(int16 left, int16 top, int16 width, int16 height); - void capturePop(char doDraw); + void freeSoundSlot(int16 slot); - void freeCollision(int16 id); - void loadSound(int16 slot, char *dataPtr, uint32 dataSize = 4294967295U); int16 checkKeys(int16 *pMousex, int16 *pMouseY, int16 *pButtons, char handleMouse); - int16 adjustKey(int16 key); - int32 loadTotFile(char *path); - void loadExtTable(void); - void loadImFile(void); void start(void); void totSub(int8 flags, char *newTotFile); void switchTotSub(int16 index, int16 skipPlay); - char *loadLocTexts(void); - Snd::SoundDesc *loadSND(const char *path, int8 arg_4); - - Imd *loadImdFile(const char *path, Video::SurfaceDesc *surfDesc, int8 flags); - int8 openImd(const char *path, int16 x, int16 y, int16 repeat, int16 flags); - void closeImd(void); - void finishImd(Imd *imdPtr); - void setImdXY(Imd *imdPtr, int16 x, int16 y); - void playImd(int16 arg_0, int16 arg_2, int16 arg_4, int16 arg_6, int16 arg_8, int16 arg_A); - void playImd(const char *path, int16 x, int16 y, int16 startFrame, int16 frames, - bool fade, bool interruptible); - int16 viewImd(Game::Imd *imdPtr, int16 arg_4); - void imdDrawFrame(Imd *imdPtr, int16 frame, int16 x, int16 y, Video::SurfaceDesc *dest = 0); - void imdRenderFrame(Imd *imdPtr); - void imdFrameUncompressor(byte *dest, byte *src); - int16 sub_2C825(Imd *imdPtr); virtual void playTot(int16 skipPlay) = 0; + virtual void clearCollisions(void) = 0; virtual int16 addNewCollision(int16 id, int16 left, int16 top, int16 right, - int16 bottom, int16 flags, int16 key, uint16 funcEnter, uint16 funcLeave) = 0; + int16 bottom, int16 flags, int16 key, uint16 funcEnter, + uint16 funcLeave) = 0; virtual void collisionsBlock(void) = 0; virtual int16 multiEdit(int16 time, int16 index, int16 *pCurPos, - InputDesc *inpDesc, int16 *collResId, int16 *collIndex) = 0; + InputDesc *inpDesc, int16 *collResId, int16 *collIndex) = 0; virtual int16 inputArea(int16 xPos, int16 yPos, int16 width, int16 height, int16 backColor, int16 frontColor, char *str, int16 fontIndex, char inpType, int16 *pTotTime, int16 *collResId, int16 *collIndex) = 0; - virtual int16 checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, - int16 *pResIndex) = 0; - virtual void prepareStart(void) = 0; + virtual int16 checkCollisions(char handleMouse, int16 deltaTime, + int16 *pResId, int16 *pResIndex) = 0; - int8 _byte_2FC9B; - int32 _dword_2F2B6; + virtual void prepareStart(void) = 0; protected: - int16 _lastCollKey; int16 _lastCollAreaIndex; int16 _lastCollId; @@ -267,14 +182,37 @@ protected: char _shouldPushColls; // Capture - static Common::Rect _captureStack[20]; - static int16 _captureCount; + Common::Rect _captureStack[20]; + int16 _captureCount; char _collStr[256]; + // For totSub() + int8 _backupedCount; + int8 _curBackupPos; + int16 _cursorXDeltaArray[5]; + int16 _cursorYDeltaArray[5]; + TotTextTable *_totTextDataArray[5]; + char *_totFileDataArray[5]; + TotResTable *_totResourceTableArray[5]; + ExtTable *_extTableArray[5]; + int16 _extHandleArray[5]; + char *_imFileDataArray[5]; + char *_variablesArray[5]; + char _curTotFileArray[5][14]; + byte *_variablesSizesArray[5]; + GobEngine *_vm; + int16 adjustKey(int16 key); + + char *loadLocTexts(void); + int32 loadTotFile(char *path); + void loadExtTable(void); + void loadImFile(void); + void setCollisions(void); + void freeCollision(int16 id); void collSub(uint16 offset); void collAreaSub(int16 index, int8 enter); int16 openLocTextFile(char *locTextFile, int language); @@ -287,17 +225,20 @@ protected: class Game_v1 : public Game { public: virtual void playTot(int16 skipPlay); + virtual void clearCollisions(void); virtual int16 addNewCollision(int16 id, int16 left, int16 top, int16 right, - int16 bottom, int16 flags, int16 key, uint16 funcEnter, uint16 funcLeave); + int16 bottom, int16 flags, int16 key, uint16 funcEnter, + uint16 funcLeave); virtual void collisionsBlock(void); virtual int16 multiEdit(int16 time, int16 index, int16 *pCurPos, - InputDesc *inpDesc, int16 *collResId, int16 *collIndex); + InputDesc *inpDesc, int16 *collResId, int16 *collIndex); virtual int16 inputArea(int16 xPos, int16 yPos, int16 width, int16 height, int16 backColor, int16 frontColor, char *str, int16 fontIndex, char inpType, int16 *pTotTime, int16 *collResId, int16 *collIndex); - virtual int16 checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, - int16 *pResIndex); + virtual int16 checkCollisions(char handleMouse, int16 deltaTime, + int16 *pResId, int16 *pResIndex); + virtual void prepareStart(void); Game_v1(GobEngine *vm); @@ -312,17 +253,20 @@ protected: class Game_v2 : public Game_v1 { public: virtual void playTot(int16 skipPlay); + virtual void clearCollisions(void); virtual int16 addNewCollision(int16 id, int16 left, int16 top, int16 right, - int16 bottom, int16 flags, int16 key, uint16 funcEnter, uint16 funcLeave); + int16 bottom, int16 flags, int16 key, uint16 funcEnter, + uint16 funcLeave); virtual void collisionsBlock(void); virtual int16 multiEdit(int16 time, int16 index, int16 *pCurPos, - InputDesc *inpDesc, int16 *collResId, int16 *collIndex); + InputDesc *inpDesc, int16 *collResId, int16 *collIndex); virtual int16 inputArea(int16 xPos, int16 yPos, int16 width, int16 height, int16 backColor, int16 frontColor, char *str, int16 fontIndex, char inpType, int16 *pTotTime, int16 *collResId, int16 *collIndex); - virtual int16 checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, - int16 *pResIndex); + virtual int16 checkCollisions(char handleMouse, int16 deltaTime, + int16 *pResId, int16 *pResIndex); + virtual void prepareStart(void); Game_v2(GobEngine *vm); @@ -342,6 +286,6 @@ protected: virtual int16 checkMousePoint(int16 all, int16 *resId, int16 *resIndex); }; -} // End of namespace Gob +} // End of namespace Gob -#endif +#endif // GOB_GAME_H diff --git a/engines/gob/game_v1.cpp b/engines/gob/game_v1.cpp index 0bda55b12d..2913a21f81 100644 --- a/engines/gob/game_v1.cpp +++ b/engines/gob/game_v1.cpp @@ -26,20 +26,19 @@ #include "common/stream.h" #include "gob/gob.h" -#include "gob/global.h" #include "gob/game.h" -#include "gob/video.h" +#include "gob/global.h" +#include "gob/util.h" #include "gob/dataio.h" -#include "gob/pack.h" -#include "gob/scenery.h" -#include "gob/inter.h" -#include "gob/parse.h" +#include "gob/music.h" +#include "gob/cdrom.h" #include "gob/draw.h" +#include "gob/inter.h" #include "gob/mult.h" -#include "gob/util.h" -#include "gob/goblin.h" -#include "gob/cdrom.h" -#include "gob/music.h" +#include "gob/video.h" +#include "gob/parse.h" +#include "gob/sound.h" +#include "gob/scenery.h" namespace Gob { @@ -55,7 +54,6 @@ void Game_v1::playTot(int16 skipPlay) { int16 breakFrom; int16 nestLevel; int32 variablesCount; - int32 i; char *filePtr; char *savedIP; @@ -74,7 +72,7 @@ void Game_v1::playTot(int16 skipPlay) { if (skipPlay == 0) { while (!_vm->_quitRequested) { - for (i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { _vm->_draw->_fontToSprite[i].sprite = -1; _vm->_draw->_fontToSprite[i].base = -1; _vm->_draw->_fontToSprite[i].width = -1; @@ -91,15 +89,15 @@ void Game_v1::playTot(int16 skipPlay) { _vm->_mult->initAll(); _vm->_mult->zeroMultData(); - for (i = 0; i < 20; i++) - _vm->_draw->_spritesArray[i] = 0; + for (int i = 0; i < SPRITES_COUNT; i++) + _vm->_draw->freeSprite(i); _vm->_draw->_spritesArray[20] = _vm->_draw->_frontSurface; _vm->_draw->_spritesArray[21] = _vm->_draw->_backSurface; _vm->_draw->_spritesArray[23] = _vm->_draw->_cursorSprites; - for (i = 0; i < 20; i++) - _soundSamples[i] = 0; + for (int i = 0; i < 20; i++) + freeSoundSlot(i); _totTextData = 0; _totResourceTable = 0; @@ -109,7 +107,7 @@ void Game_v1::playTot(int16 skipPlay) { _totToLoad[0] = 0; - if (_curTotFile[0] == 0 && _totFileData == 0) + if ((_curTotFile[0] == 0) && (_totFileData == 0)) break; loadTotFile(_curTotFile); @@ -130,35 +128,40 @@ void Game_v1::playTot(int16 skipPlay) { debugC(4, kDebugFileIO, "IMA: %s", _curImaFile); debugC(4, kDebugFileIO, "EXT: %s", _curExtFile); - filePtr = (char *)_totFileData + 0x30; + filePtr = (char *) _totFileData + 0x30; _totTextData = 0; - if (READ_LE_UINT32(filePtr) != (uint32)-1) { + if (READ_LE_UINT32(filePtr) != (uint32) -1) { _totTextData = new TotTextTable; - _totTextData->dataPtr = (_totFileData + READ_LE_UINT32((char *)_totFileData + 0x30)); - Common::MemoryReadStream totTextData((byte *) _totTextData->dataPtr, 4294967295U); + _totTextData->dataPtr = + (_totFileData + READ_LE_UINT32((char *) _totFileData + 0x30)); + Common::MemoryReadStream totTextData((byte *) _totTextData->dataPtr, + 4294967295U); _totTextData->itemsCount = totTextData.readSint16LE(); _totTextData->items = new TotTextItem[_totTextData->itemsCount]; - for (i = 0; i < _totTextData->itemsCount; ++i) { + for (int i = 0; i < _totTextData->itemsCount; ++i) { _totTextData->items[i].offset = totTextData.readSint16LE(); _totTextData->items[i].size = totTextData.readSint16LE(); } } - filePtr = (char *)_totFileData + 0x34; + filePtr = (char *) _totFileData + 0x34; _totResourceTable = 0; - if (READ_LE_UINT32(filePtr) != (uint32)-1) { + if (READ_LE_UINT32(filePtr) != (uint32) -1) { _totResourceTable = new TotResTable; - _totResourceTable->dataPtr = _totFileData + READ_LE_UINT32((char *)_totFileData + 0x34); - Common::MemoryReadStream totResTable((byte *) _totResourceTable->dataPtr, 4294967295U); + _totResourceTable->dataPtr = + _totFileData + READ_LE_UINT32((char *) _totFileData + 0x34); + Common::MemoryReadStream totResTable((byte *) _totResourceTable->dataPtr, + 4294967295U); _totResourceTable->itemsCount = totResTable.readSint16LE(); _totResourceTable->unknown = totResTable.readByte(); - _totResourceTable->items = new TotResItem[_totResourceTable->itemsCount]; - for (i = 0; i < _totResourceTable->itemsCount; ++i) { + _totResourceTable->items = + new TotResItem[_totResourceTable->itemsCount]; + for (int i = 0; i < _totResourceTable->itemsCount; ++i) { _totResourceTable->items[i].offset = totResTable.readSint32LE(); _totResourceTable->items[i].size = totResTable.readSint16LE(); _totResourceTable->items[i].width = totResTable.readSint16LE(); @@ -169,16 +172,18 @@ void Game_v1::playTot(int16 skipPlay) { loadImFile(); loadExtTable(); - _vm->_global->_inter_animDataSize = READ_LE_UINT16((char *)_totFileData + 0x38); + _vm->_global->_inter_animDataSize = + READ_LE_UINT16((char *) _totFileData + 0x38); if (_vm->_global->_inter_variables == 0) { - variablesCount = READ_LE_UINT16((char *)_totFileData + 0x2c); + variablesCount = READ_LE_UINT16((char *) _totFileData + 0x2C); _vm->_global->_inter_variables = new char[variablesCount * 4]; _vm->_global->_inter_variablesSizes = new byte[variablesCount * 4]; _vm->_global->clearVars(variablesCount); } - _vm->_global->_inter_execPtr = (char *)_totFileData; - _vm->_global->_inter_execPtr += READ_LE_UINT32((char *)_totFileData + 0x64); + _vm->_global->_inter_execPtr = (char *) _totFileData; + _vm->_global->_inter_execPtr += + READ_LE_UINT32((char *) _totFileData + 0x64); _vm->_inter->renewTimeInVars(); @@ -190,9 +195,9 @@ void Game_v1::playTot(int16 skipPlay) { _vm->_inter->callSub(2); if (_totToLoad[0] != 0) - _vm->_inter->_terminate = false; + _vm->_inter->_terminate = 0; - variablesCount = READ_LE_UINT32((char *)_totFileData + 0x2c); + variablesCount = READ_LE_UINT32((char *) _totFileData + 0x2C); _vm->_draw->blitInvalidated(); delete[] _totFileData; _totFileData = 0; @@ -218,24 +223,21 @@ void Game_v1::playTot(int16 skipPlay) { _extTable = 0; if (_extHandle >= 0) - _vm->_dataio->closeData(_extHandle); + _vm->_dataIO->closeData(_extHandle); _extHandle = -1; - for (i = 0; i < *_vm->_scenery->_pCaptureCounter; i++) + for (int i = 0; i < *_vm->_scenery->_pCaptureCounter; i++) capturePop(0); _vm->_mult->checkFreeMult(); _vm->_mult->freeAll(); - for (i = 0; i < 20; i++) { - if (_vm->_draw->_spritesArray[i] != 0) - _vm->_video->freeSurfDesc(_vm->_draw->_spritesArray[i]); - _vm->_draw->_spritesArray[i] = 0; - } + for (int i = 0; i < SPRITES_COUNT; i++) + _vm->_draw->freeSprite(i); _vm->_snd->stopSound(0); - for (i = 0; i < 20; i++) + for (int i = 0; i < 20; i++) freeSoundSlot(i); if (_totToLoad[0] == 0) @@ -254,25 +256,26 @@ void Game_v1::playTot(int16 skipPlay) { } void Game_v1::clearCollisions() { - int16 i; - for (i = 0; i < 250; i++) { + for (int i = 0; i < 250; i++) { _collisionAreas[i].id = 0; _collisionAreas[i].left = -1; } } -int16 Game_v1::addNewCollision(int16 id, int16 left, int16 top, int16 right, int16 bottom, - int16 flags, int16 key, uint16 funcEnter, uint16 funcLeave) { - int16 i; +int16 Game_v1::addNewCollision(int16 id, int16 left, int16 top, + int16 right, int16 bottom, int16 flags, int16 key, + uint16 funcEnter, uint16 funcLeave) { Collision *ptr; debugC(5, kDebugCollisions, "addNewCollision"); - debugC(5, kDebugCollisions, "id = %x", id); - debugC(5, kDebugCollisions, "left = %d, top = %d, right = %d, bottom = %d", left, top, right, bottom); - debugC(5, kDebugCollisions, "flags = %x, key = %x", flags, key); - debugC(5, kDebugCollisions, "funcEnter = %d, funcLeave = %d", funcEnter, funcLeave); - - for (i = 0; i < 250; i++) { + debugC(5, kDebugCollisions, "id = %X", id); + debugC(5, kDebugCollisions, "left = %d, top = %d, right = %d, bottom = %d", + left, top, right, bottom); + debugC(5, kDebugCollisions, "flags = %X, key = %X", flags, key); + debugC(5, kDebugCollisions, "funcEnter = %d, funcLeave = %d", + funcEnter, funcLeave); + + for (int i = 0; i < 250; i++) { if (_collisionAreas[i].left != -1) continue; @@ -298,8 +301,7 @@ void Game_v1::pushCollisions(char all) { int16 size; debugC(1, kDebugCollisions, "pushCollisions"); - for (size = 0, srcPtr = _collisionAreas; srcPtr->left != -1; - srcPtr++) { + for (size = 0, srcPtr = _collisionAreas; srcPtr->left != -1; srcPtr++) { if (all || (srcPtr->id & 0x8000)) size++; } @@ -329,14 +331,13 @@ void Game_v1::popCollisions(void) { srcPtr = _collStack[_collStackSize]; memcpy(destPtr, srcPtr, - _collStackElemSizes[_collStackSize] * - sizeof(Collision)); + _collStackElemSizes[_collStackSize] * sizeof(Collision)); delete[] _collStack[_collStackSize]; } -int16 Game_v1::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, - int16 *pResIndex) { +int16 Game_v1::checkCollisions(char handleMouse, int16 deltaTime, + int16 *pResId, int16 *pResIndex) { char *savedIP; int16 resIndex; int16 key; @@ -355,15 +356,13 @@ int16 Game_v1::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, resIndex = 0; - if (_vm->_draw->_cursorIndex == -1 && handleMouse != 0 - && _lastCollKey == 0) { - _lastCollKey = - checkMousePoint(1, &_lastCollId, - &_lastCollAreaIndex); + if ((_vm->_draw->_cursorIndex == -1) && (handleMouse != 0) && + (_lastCollKey == 0)) { + _lastCollKey = checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex); - if (_lastCollKey != 0 && (_lastCollId & 0x8000) != 0) { + if ((_lastCollKey != 0) && ((_lastCollId & 0x8000) != 0)) { savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = (char *)_totFileData + + _vm->_global->_inter_execPtr = (char *) _totFileData + _collisionAreas[_lastCollAreaIndex].funcEnter; _vm->_inter->funcBlock(0); @@ -382,7 +381,7 @@ int16 Game_v1::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, return 0; } - if (_vm->_draw->_noInvalidated == 0) { + if (!_vm->_draw->_noInvalidated) { if (handleMouse) _vm->_draw->animateCursor(-1); else @@ -397,7 +396,7 @@ int16 Game_v1::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, // and the return value is then discarded. if (deltaTime < 0) { uint32 curtime = _vm->_util->getTimeKey(); - if (deltaTime == -1 || curtime + deltaTime > timeKey) { + if ((deltaTime == -1) || ((curtime + deltaTime) > timeKey)) { if (pResId != 0) *pResId = 0; @@ -408,10 +407,10 @@ int16 Game_v1::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, } } - key = checkKeys(&_vm->_global->_inter_mouseX, &_vm->_global->_inter_mouseY, - &_mouseButtons, handleMouse); + key = checkKeys(&_vm->_global->_inter_mouseX, + &_vm->_global->_inter_mouseY, &_mouseButtons, handleMouse); - if (handleMouse == 0 && _mouseButtons != 0) { + if ((handleMouse == 0) && (_mouseButtons != 0)) { _vm->_util->waitMouseRelease(0); key = 3; } @@ -427,10 +426,10 @@ int16 Game_v1::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, if (pResIndex != 0) *pResIndex = 0; - if (_lastCollKey != 0 && - _collisionAreas[_lastCollAreaIndex].funcLeave != 0) { + if ((_lastCollKey != 0) && + (_collisionAreas[_lastCollAreaIndex].funcLeave != 0)) { savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = (char *)_totFileData + + _vm->_global->_inter_execPtr = (char *) _totFileData + _collisionAreas[_lastCollAreaIndex].funcLeave; _vm->_inter->funcBlock(0); @@ -450,9 +449,8 @@ int16 Game_v1::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, if (deltaTime <= 0) { if (handleMouse == 1) _vm->_util->waitMouseRelease(1); - } else if (deltaTime > 0) { + } else if (deltaTime > 0) _vm->_util->delay(deltaTime); - } _vm->_draw->animateCursor(-1); if (pResId != 0) @@ -463,16 +461,15 @@ int16 Game_v1::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, if (pResIndex != 0) *pResIndex = resIndex; - if (key != 0 || (pResId != 0 && *pResId != 0)) { - if (handleMouse == 1 && (deltaTime <= 0 - || _mouseButtons == 0)) + if ((key != 0) || ((pResId != 0) && (*pResId != 0))) { + if ((handleMouse == 1) && + ((deltaTime <= 0) || (_mouseButtons == 0))) _vm->_draw->blitCursor(); - if (_lastCollKey != 0 && - _collisionAreas[_lastCollAreaIndex].funcLeave != 0) { + if ((_lastCollKey != 0) && + (_collisionAreas[_lastCollAreaIndex].funcLeave != 0)) { savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = - (char *)_totFileData + + _vm->_global->_inter_execPtr = (char *) _totFileData + _collisionAreas[_lastCollAreaIndex].funcLeave; _vm->_inter->funcBlock(0); @@ -482,11 +479,10 @@ int16 Game_v1::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, return key; } - if (_lastCollKey != 0 && - _collisionAreas[_lastCollAreaIndex].funcLeave != 0) { + if ((_lastCollKey != 0) && + (_collisionAreas[_lastCollAreaIndex].funcLeave != 0)) { savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = - (char *)_totFileData + + _vm->_global->_inter_execPtr = (char *) _totFileData + _collisionAreas[_lastCollAreaIndex].funcLeave; _vm->_inter->funcBlock(0); @@ -494,14 +490,11 @@ int16 Game_v1::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, } _lastCollKey = - checkMousePoint(1, &_lastCollId, - &_lastCollAreaIndex); + checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex); - if (_lastCollKey != 0 - && (_lastCollId & 0x8000) != 0) { + if ((_lastCollKey != 0) && ((_lastCollId & 0x8000) != 0)) { savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = - (char *)_totFileData + + _vm->_global->_inter_execPtr = (char *) _totFileData + _collisionAreas[_lastCollAreaIndex].funcEnter; _vm->_inter->funcBlock(0); @@ -509,22 +502,18 @@ int16 Game_v1::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, } } else { - if (handleMouse != 0 && - (_vm->_global->_inter_mouseX != _vm->_draw->_cursorX - || _vm->_global->_inter_mouseY != _vm->_draw->_cursorY)) { + if ((handleMouse != 0) && + ((_vm->_global->_inter_mouseX != _vm->_draw->_cursorX) || + (_vm->_global->_inter_mouseY != _vm->_draw->_cursorY))) { oldIndex = _lastCollAreaIndex; oldId = _lastCollId; - key = - checkMousePoint(1, - &_lastCollId, - &_lastCollAreaIndex); + key = checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex); if (key != _lastCollKey) { - if (_lastCollKey != 0 - && (oldId & 0x8000) != 0) { + if ((_lastCollKey != 0) && ((oldId & 0x8000) != 0)) { savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = (char *)_totFileData + + _vm->_global->_inter_execPtr = (char *) _totFileData + _collisionAreas[oldIndex].funcLeave; _vm->_inter->funcBlock(0); @@ -532,9 +521,9 @@ int16 Game_v1::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, } _lastCollKey = key; - if (_lastCollKey != 0 && (_lastCollId & 0x8000) != 0) { + if ((_lastCollKey != 0) && ((_lastCollId & 0x8000) != 0)) { savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = (char *)_totFileData + + _vm->_global->_inter_execPtr = (char *) _totFileData + _collisionAreas[_lastCollAreaIndex].funcEnter; _vm->_inter->funcBlock(0); @@ -553,8 +542,6 @@ int16 Game_v1::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, } void Game_v1::prepareStart(void) { - int16 i; - clearCollisions(); _vm->_global->_pPaletteDesc->unused2 = _vm->_draw->_unusedPalette2; @@ -565,32 +552,30 @@ void Game_v1::prepareStart(void) { _vm->_draw->initScreen(); _vm->_video->fillRect(_vm->_draw->_backSurface, 0, 0, 319, 199, 1); - _vm->_draw->_frontSurface = _vm->_global->_pPrimarySurfDesc; + _vm->_draw->_frontSurface = _vm->_global->_primarySurfDesc; _vm->_video->fillRect(_vm->_draw->_frontSurface, 0, 0, 319, 199, 1); _vm->_util->setMousePos(152, 92); + _vm->_draw->_cursorX = _vm->_global->_inter_mouseX = 152; + _vm->_draw->_cursorY = _vm->_global->_inter_mouseY = 92; - _vm->_draw->_cursorX = 152; - _vm->_global->_inter_mouseX = 152; - - _vm->_draw->_cursorY = 92; - _vm->_global->_inter_mouseY = 92; _vm->_draw->_invalidatedCount = 0; - _vm->_draw->_noInvalidated = 1; - _vm->_draw->_applyPal = 0; - _vm->_draw->_paletteCleared = 0; + _vm->_draw->_noInvalidated = true; + _vm->_draw->_applyPal = false; + _vm->_draw->_paletteCleared = false; _vm->_draw->_cursorWidth = 16; _vm->_draw->_cursorHeight = 16; _vm->_draw->_transparentCursor = 1; - for (i = 0; i < 40; i++) { + for (int i = 0; i < 40; i++) { _vm->_draw->_cursorAnimLow[i] = -1; _vm->_draw->_cursorAnimDelays[i] = 0; _vm->_draw->_cursorAnimHigh[i] = 0; } _vm->_draw->_cursorAnimLow[1] = 0; - _vm->_draw->_cursorSprites = _vm->_video->initSurfDesc(_vm->_global->_videoMode, 32, 16, 2); + _vm->_draw->_cursorSprites = + _vm->_video->initSurfDesc(_vm->_global->_videoMode, 32, 16, 2); _vm->_draw->_scummvmCursor = _vm->_video->initSurfDesc(_vm->_global->_videoMode, 16, 16, SCUMMVM_CURSOR); _vm->_draw->_renderFlags = 0; @@ -641,12 +626,12 @@ void Game_v1::collisionsBlock(void) { _vm->_global->_inter_execPtr++; count = *_vm->_global->_inter_execPtr++; _handleMouse = _vm->_global->_inter_execPtr[0]; - deltaTime = 1000 * (byte)_vm->_global->_inter_execPtr[1]; - descIndex2 = (byte)_vm->_global->_inter_execPtr[2]; - stackPos2 = (byte)_vm->_global->_inter_execPtr[3]; - descIndex = (byte)_vm->_global->_inter_execPtr[4]; + deltaTime = 1000 * (byte) _vm->_global->_inter_execPtr[1]; + descIndex2 = (byte) _vm->_global->_inter_execPtr[2]; + stackPos2 = (byte) _vm->_global->_inter_execPtr[3]; + descIndex = (byte) _vm->_global->_inter_execPtr[4]; - if (stackPos2 != 0 || descIndex != 0) + if ((stackPos2 != 0) || (descIndex != 0)) deltaTime /= 100; timeVal = deltaTime; @@ -664,12 +649,11 @@ void Game_v1::collisionsBlock(void) { if ((cmd & 0x40) != 0) { cmd -= 0x40; - cmdHigh = (byte)*_vm->_global->_inter_execPtr; + cmdHigh = (byte) *_vm->_global->_inter_execPtr; _vm->_global->_inter_execPtr++; cmdHigh <<= 8; - } else { + } else cmdHigh = 0; - } if ((cmd & 0x80) != 0) { left = _vm->_parse->parseValExpr(); @@ -682,7 +666,7 @@ void Game_v1::collisionsBlock(void) { width = _vm->_inter->load16(); height = _vm->_inter->load16(); } - cmd &= 0x7f; + cmd &= 0x7F; debugC(1, kDebugCollisions, "collisionsBlock(%d)", cmd); @@ -696,14 +680,14 @@ void Game_v1::collisionsBlock(void) { case 9: case 10: - _vm->_util->waitKey(); + _vm->_util->clearKeyBuf(); var_22 = 1; key = _vm->_parse->parseVarIndex(); descArray[index].fontIndex = _vm->_inter->load16(); descArray[index].backColor = *_vm->_global->_inter_execPtr++; descArray[index].frontColor = *_vm->_global->_inter_execPtr++; - if (cmd < 5 || cmd > 8) { + if ((cmd < 5) || (cmd > 8)) { descArray[index].ptr = 0; } else { descArray[index].ptr = _vm->_global->_inter_execPtr + 2; @@ -714,25 +698,18 @@ void Game_v1::collisionsBlock(void) { break; if ((cmd & 1) == 0) { - addNewCollision(curCmd + 0x8000, left, - top, - left + - width * - _vm->_draw->_fonts[descArray[index].fontIndex]-> - itemWidth - 1, top + height - 1, cmd, key, - 0, - _vm->_global->_inter_execPtr - (char *)_totFileData); + addNewCollision(curCmd + 0x8000, left, top, left + width * + _vm->_draw->_fonts[descArray[index].fontIndex]->itemWidth - 1, + top + height - 1, cmd, key, 0, + _vm->_global->_inter_execPtr - (char *) _totFileData); _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr); } else { - addNewCollision(curCmd + 0x8000, left, - top, - left + - width * - _vm->_draw->_fonts[descArray[index].fontIndex]-> - itemWidth - 1, top + height - 1, cmd, key, - 0, 0); + addNewCollision(curCmd + 0x8000, left, top, left + width * + _vm->_draw->_fonts[descArray[index].fontIndex]->itemWidth - 1, + top + height - 1, cmd, key, 0, 0); } index++; break; @@ -743,13 +720,13 @@ void Game_v1::collisionsBlock(void) { flags = _vm->_inter->load16() & 3; addNewCollision(curCmd + 0x8000, left, top, - left + width - 1, - top + height - 1, + left + width - 1, top + height - 1, (flags << 4) + cmdHigh + 2, key, - _vm->_global->_inter_execPtr - (char *)_totFileData, 0); + _vm->_global->_inter_execPtr - (char *) _totFileData, 0); _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr); break; case 20: @@ -765,28 +742,30 @@ void Game_v1::collisionsBlock(void) { left + width - 1, top + height - 1, (flags << 4) + cmdHigh + 2, key, 0, - _vm->_global->_inter_execPtr - (char *)_totFileData); + _vm->_global->_inter_execPtr - (char *) _totFileData); _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr); break; case 0: _vm->_global->_inter_execPtr += 6; startIP = _vm->_global->_inter_execPtr; _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr); key = curCmd + 0xA000; addNewCollision(curCmd + 0x8000, left, top, - left + width - 1, - top + height - 1, + left + width - 1, top + height - 1, cmd + cmdHigh, key, - startIP - (char *)_totFileData, - _vm->_global->_inter_execPtr - (char *)_totFileData); + startIP - (char *) _totFileData, + _vm->_global->_inter_execPtr - (char *) _totFileData); _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr); break; case 1: @@ -796,33 +775,33 @@ void Game_v1::collisionsBlock(void) { startIP = _vm->_global->_inter_execPtr; _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr); if (key == 0) - key = curCmd + 0xa000; + key = curCmd + 0xA000; addNewCollision(curCmd + 0x8000, left, top, - left + width - 1, - top + height - 1, + left + width - 1, top + height - 1, (flags << 4) + cmd + cmdHigh, key, - startIP - (char *)_totFileData, - _vm->_global->_inter_execPtr - (char *)_totFileData); + startIP - (char *) _totFileData, + _vm->_global->_inter_execPtr - (char *) _totFileData); _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr); break; } } _forceHandleMouse = 0; - _vm->_util->waitKey(); + _vm->_util->clearKeyBuf(); do { if (var_22 != 0) { - key = - multiEdit(deltaTime, index, &curEditIndex, - descArray, &_activeCollResId, &_activeCollIndex); + key = multiEdit(deltaTime, index, &curEditIndex, + descArray, &_activeCollResId, &_activeCollIndex); - if (key == 0x1c0d) { + if (key == 0x1C0D) { for (i = 0; i < 250; i++) { if (_collisionAreas[i].left == -1) continue; @@ -833,27 +812,24 @@ void Game_v1::collisionsBlock(void) { if ((_collisionAreas[i].flags & 1) != 0) continue; - if ((_collisionAreas[i].flags & 0x0f) <= 2) + if ((_collisionAreas[i].flags & 0x0F) <= 2) continue; collResId = _collisionAreas[i].id; _activeCollResId = collResId; - collResId &= 0x7fff; + collResId &= 0x7FFF; _activeCollIndex = i; break; } break; } - } else { - key = - checkCollisions(_handleMouse, -deltaTime, + } else + key = checkCollisions(_handleMouse, -deltaTime, &_activeCollResId, &_activeCollIndex); - } - if ((key & 0xff) >= ' ' && (key & 0xff) <= 0xff && - (key >> 8) > 1 && (key >> 8) < 12) { - key = '0' + (((key >> 8) - 1) % 10) + (key & 0xff00); - } + if (((key & 0xFF) >= ' ') && ((key & 0xFF) <= 0xFF) && + ((key >> 8) > 1) && ((key >> 8) < 12)) + key = '0' + (((key >> 8) - 1) % 10) + (key & 0xFF00); if (_activeCollResId == 0) { if (key != 0) { @@ -861,16 +837,13 @@ void Game_v1::collisionsBlock(void) { if (_collisionAreas[i].left == -1) continue; - if ((_collisionAreas[i]. - id & 0x8000) == 0) + if ((_collisionAreas[i].id & 0x8000) == 0) continue; - if (_collisionAreas[i].key == key - || _collisionAreas[i].key == - 0x7fff) { + if ((_collisionAreas[i].key == key) || + (_collisionAreas[i].key == 0x7FFF)) { - _activeCollResId = - _collisionAreas[i].id; + _activeCollResId = _collisionAreas[i].id; _activeCollIndex = i; break; } @@ -884,13 +857,14 @@ void Game_v1::collisionsBlock(void) { if ((_collisionAreas[i].id & 0x8000) == 0) continue; - if ((_collisionAreas[i].key & 0xff00) != 0) + if ((_collisionAreas[i].key & 0xFF00) != 0) continue; if (_collisionAreas[i].key == 0) continue; - if (adjustKey(key & 0xff) == adjustKey(_collisionAreas[i].key) || _collisionAreas[i].key == 0x7fff) { + if ((adjustKey(key & 0xFF) == adjustKey(_collisionAreas[i].key)) || + (_collisionAreas[i].key == 0x7FFF)) { _activeCollResId = _collisionAreas[i].id; _activeCollIndex = i; break; @@ -899,12 +873,14 @@ void Game_v1::collisionsBlock(void) { } } else { - if (deltaTime != 0 && VAR(16) == 0) { + if ((deltaTime != 0) && (VAR(16) == 0)) { if (stackPos2 != 0) { collStackPos = 0; collPtr = _collisionAreas; - for (i = 0, collPtr = _collisionAreas; collPtr->left != -1; i++, collPtr++) { + for (i = 0, collPtr = _collisionAreas; + collPtr->left != -1; i++, collPtr++) { + if ((collPtr->id & 0x8000) == 0) continue; @@ -917,12 +893,13 @@ void Game_v1::collisionsBlock(void) { WRITE_VAR(2, _vm->_global->_inter_mouseX); WRITE_VAR(3, _vm->_global->_inter_mouseY); WRITE_VAR(4, _mouseButtons); - WRITE_VAR(16, array[(uint16)_activeCollResId & ~0x8000]); + WRITE_VAR(16, array[(uint16) _activeCollResId & ~0x8000]); if (collPtr->funcLeave != 0) { timeKey = _vm->_util->getTimeKey(); savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = (char *)_totFileData + collPtr->funcLeave; + _vm->_global->_inter_execPtr = + (char *) _totFileData + collPtr->funcLeave; _shouldPushColls = 1; savedCollStackSize = _collStackSize; _vm->_inter->funcBlock(0); @@ -932,7 +909,8 @@ void Game_v1::collisionsBlock(void) { _shouldPushColls = 0; _vm->_global->_inter_execPtr = savedIP; - deltaTime = timeVal - (_vm->_util->getTimeKey() - timeKey); + deltaTime = timeVal - + (_vm->_util->getTimeKey() - timeKey); if (deltaTime < 2) deltaTime = 2; @@ -1006,13 +984,12 @@ void Game_v1::collisionsBlock(void) { WRITE_VAR(2, _vm->_global->_inter_mouseX); WRITE_VAR(3, _vm->_global->_inter_mouseY); WRITE_VAR(4, _mouseButtons); - WRITE_VAR(16, array[(uint16)_activeCollResId & ~0x8000]); + WRITE_VAR(16, array[(uint16) _activeCollResId & ~0x8000]); if (_collisionAreas[_activeCollIndex].funcEnter != 0) { savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = (char *)_totFileData + - _collisionAreas[_activeCollIndex]. - funcEnter; + _vm->_global->_inter_execPtr = (char *) _totFileData + + _collisionAreas[_activeCollIndex].funcEnter; _shouldPushColls = 1; @@ -1027,9 +1004,9 @@ void Game_v1::collisionsBlock(void) { WRITE_VAR(16, 0); _activeCollResId = 0; } - while (_activeCollResId == 0 && !_vm->_inter->_terminate && !_vm->_quitRequested); + while ((_activeCollResId == 0) && !_vm->_inter->_terminate && !_vm->_quitRequested); - if (((uint16)_activeCollResId & ~0x8000) == collResId) { + if (((uint16) _activeCollResId & ~0x8000) == collResId) { collStackPos = 0; var_24 = 0; var_26 = 1; @@ -1040,13 +1017,13 @@ void Game_v1::collisionsBlock(void) { if ((_collisionAreas[i].id & 0x8000) == 0) continue; - if ((_collisionAreas[i].flags & 0x0f) < 3) + if ((_collisionAreas[i].flags & 0x0F) < 3) continue; - if ((_collisionAreas[i].flags & 0x0f) > 10) + if ((_collisionAreas[i].flags & 0x0F) > 10) continue; - if ((_collisionAreas[i].flags & 0x0f) > 8) { + if ((_collisionAreas[i].flags & 0x0F) > 8) { char *ptr; strcpy(_tempStr, GET_VARO_STR(_collisionAreas[i].key)); while ((ptr = strchr(_tempStr, ' ')) != 0) { @@ -1056,13 +1033,13 @@ void Game_v1::collisionsBlock(void) { WRITE_VARO_STR(_collisionAreas[i].key, _tempStr); } - if ((_collisionAreas[i].flags & 0x0f) >= 5 && - (_collisionAreas[i].flags & 0x0f) <= 8) { + if (((_collisionAreas[i].flags & 0x0F) >= 5) && + ((_collisionAreas[i].flags & 0x0F) <= 8)) { str = descArray[var_24].ptr; strcpy(_tempStr, GET_VARO_STR(_collisionAreas[i].key)); - if ((_collisionAreas[i].flags & 0x0f) < 7) + if ((_collisionAreas[i].flags & 0x0F) < 7) _vm->_util->prepareStr(_tempStr); int16 pos = 0; @@ -1072,7 +1049,7 @@ void Game_v1::collisionsBlock(void) { str += strlen(str) + 1; - if ((_collisionAreas[i].flags & 0x0f) < 7) + if ((_collisionAreas[i].flags & 0x0F) < 7) _vm->_util->prepareStr(_collStr); if (strcmp(_tempStr, _collStr) == 0) { @@ -1089,7 +1066,7 @@ void Game_v1::collisionsBlock(void) { var_26++; } - if (collStackPos != (int16)VAR(17)) + if (collStackPos != (int16) VAR(17)) WRITE_VAR(17, 0); else WRITE_VAR(17, 1); @@ -1097,26 +1074,25 @@ void Game_v1::collisionsBlock(void) { savedIP = 0; if (!_vm->_inter->_terminate) { - savedIP = (char *)_totFileData + + savedIP = (char *) _totFileData + _collisionAreas[_activeCollIndex].funcLeave; WRITE_VAR(2, _vm->_global->_inter_mouseX); WRITE_VAR(3, _vm->_global->_inter_mouseY); WRITE_VAR(4, _mouseButtons); - if (VAR(16) == 0) { - WRITE_VAR(16, array[(uint16)_activeCollResId & ~0x8000]); - } + if (VAR(16) == 0) + WRITE_VAR(16, array[(uint16) _activeCollResId & ~0x8000]); } - for (curCmd = 0; curCmd < count; curCmd++) { + for (curCmd = 0; curCmd < count; curCmd++) freeCollision(curCmd + 0x8000); - } + _vm->_global->_inter_execPtr = savedIP; } -int16 Game_v1::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * inpDesc, - int16 *collResId, int16 *collIndex) { +int16 Game_v1::multiEdit(int16 time, int16 index, int16 *pCurPos, + InputDesc * inpDesc, int16 *collResId, int16 *collIndex) { Collision *collArea; int16 descInd; int16 key; @@ -1133,10 +1109,10 @@ int16 Game_v1::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * in if ((collArea->id & 0x8000) == 0) continue; - if ((collArea->flags & 0x0f) < 3) + if ((collArea->flags & 0x0F) < 3) continue; - if ((collArea->flags & 0x0f) > 10) + if ((collArea->flags & 0x0F) > 10) continue; strcpy(_tempStr, GET_VARO_STR(collArea->key)); @@ -1176,10 +1152,10 @@ int16 Game_v1::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * in if ((collArea->id & 0x8000) == 0) continue; - if ((collArea->flags & 0x0f) < 3) + if ((collArea->flags & 0x0F) < 3) continue; - if ((collArea->flags & 0x0f) > 10) + if ((collArea->flags & 0x0F) > 10) continue; if (descInd == *pCurPos) { @@ -1209,10 +1185,10 @@ int16 Game_v1::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * in if (*collResId == 0) return 0; - if ((_collisionAreas[*collIndex].flags & 0x0f) < 3) + if ((_collisionAreas[*collIndex].flags & 0x0F) < 3) return 0; - if ((_collisionAreas[*collIndex].flags & 0x0f) > 10) + if ((_collisionAreas[*collIndex].flags & 0x0F) > 10) return 0; *pCurPos = 0; @@ -1225,10 +1201,10 @@ int16 Game_v1::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * in if ((collArea->id & 0x8000) == 0) continue; - if ((collArea->flags & 0x0f) < 3) + if ((collArea->flags & 0x0F) < 3) continue; - if ((collArea->flags & 0x0f) > 10) + if ((collArea->flags & 0x0F) > 10) continue; if (i == *collIndex) @@ -1238,11 +1214,11 @@ int16 Game_v1::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * in } break; - case 0x3b00: - case 0x3c00: - case 0x3d00: - case 0x3e00: - case 0x3f00: + case 0x3B00: + case 0x3C00: + case 0x3D00: + case 0x3E00: + case 0x3F00: case 0x4000: case 0x4100: case 0x4200: @@ -1250,7 +1226,7 @@ int16 Game_v1::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * in case 0x4400: return key; - case 0x1c0d: + case 0x1C0D: if (index == 1) return key; @@ -1291,8 +1267,8 @@ int16 Game_v1::inputArea(int16 xPos, int16 yPos, int16 width, int16 height, int16 flag; int16 savedKey; - if (_handleMouse != 0 && - (_vm->_global->_useMouse != 0 || _forceHandleMouse != 0)) + if ((_handleMouse != 0) && + ((_vm->_global->_useMouse != 0) || (_forceHandleMouse != 0))) handleMouse = 1; else handleMouse = 0; @@ -1342,9 +1318,8 @@ int16 Game_v1::inputArea(int16 xPos, int16 yPos, int16 width, int16 height, _vm->_draw->_backColor = frontColor; _vm->_draw->spriteOperation(DRAW_FILLRECT); - if (flag != 0) { + if (flag != 0) key = checkCollisions(handleMouse, -1, collResId, collIndex); - } flag = 0; key = checkCollisions(handleMouse, -300, collResId, collIndex); @@ -1374,7 +1349,7 @@ int16 Game_v1::inputArea(int16 xPos, int16 yPos, int16 width, int16 height, _vm->_draw->_destSpriteY = yPos + (height - 8) / 2; _vm->_draw->spriteOperation(DRAW_PRINTTEXT); - if (key != 0 || *collResId != 0) + if ((key != 0) || (*collResId != 0)) break; key = checkCollisions(handleMouse, -300, collResId, collIndex); @@ -1386,41 +1361,41 @@ int16 Game_v1::inputArea(int16 xPos, int16 yPos, int16 width, int16 height, *collResId = 0; break; } - } - if (key != 0 || *collResId != 0) + + if ((key != 0) || (*collResId != 0)) break; if (_vm->_inter->_terminate) return 0; } - if (key == 0 || *collResId != 0 || _vm->_inter->_terminate) + if ((key == 0) || (*collResId != 0) || _vm->_inter->_terminate) return 0; switch (key) { - case 0x4d00: // Right Arrow - if (pos < strlen(str) && pos < editSize - 1) { + case 0x4D00: // Right Arrow + if ((pos < strlen(str)) && (pos < (editSize - 1))) { pos++; continue; } return 0x5000; - case 0x4b00: // Left Arrow + case 0x4B00: // Left Arrow if (pos > 0) { pos--; continue; } return 0x4800; - case 0xe08: // Backspace + case 0xE08: // Backspace if (pos > 0) { _vm->_util->cutFromStr(str, pos - 1, 1); pos--; continue; } - case 0x5300: // Del + case 0x5300: // Del if (pos >= strlen(str)) continue; @@ -1428,29 +1403,29 @@ int16 Game_v1::inputArea(int16 xPos, int16 yPos, int16 width, int16 height, _vm->_util->cutFromStr(str, pos, 1); continue; - case 0x1c0d: // Enter - case 0x3b00: // F1 - case 0x3c00: // F2 - case 0x3d00: // F3 - case 0x3e00: // F4 - case 0x3f00: // F5 - case 0x4000: // F6 - case 0x4100: // F7 - case 0x4200: // F8 - case 0x4300: // F9 - case 0x4400: // F10 - case 0x4800: // Up arrow - case 0x5000: // Down arrow + case 0x1C0D: // Enter + case 0x3B00: // F1 + case 0x3C00: // F2 + case 0x3D00: // F3 + case 0x3E00: // F4 + case 0x3F00: // F5 + case 0x4000: // F6 + case 0x4100: // F7 + case 0x4200: // F8 + case 0x4300: // F9 + case 0x4400: // F10 + case 0x4800: // Up arrow + case 0x5000: // Down arrow return key; - case 0x11b: // Escape + case 0x11B: // Escape if (_vm->_global->_useMouse != 0) continue; _forceHandleMouse = !_forceHandleMouse; - if (_handleMouse != 0 && - (_vm->_global->_useMouse != 0 || _forceHandleMouse != 0)) + if ((_handleMouse != 0) && + ((_vm->_global->_useMouse != 0) || (_forceHandleMouse != 0))) handleMouse = 1; else handleMouse = 0; @@ -1464,15 +1439,14 @@ int16 Game_v1::inputArea(int16 xPos, int16 yPos, int16 width, int16 height, default: savedKey = key; - key &= 0xff; + key &= 0xFF; - if ((inpType == 9 || inpType == 10) && key >= ' ' - && key <= 0xff) { + if (((inpType == 9) || (inpType == 10)) && + (key >= ' ') && (key <= 0xFF)) { str1 = "0123456789-.,+ "; str2 = "0123456789-,,+ "; - if ((savedKey >> 8) > 1 - && (savedKey >> 8) < 12) + if (((savedKey >> 8) > 1) && ((savedKey >> 8) < 12)) key = ((savedKey >> 8) - 1) % 10 + '0'; for (i = 0; str1[i] != 0; i++) { @@ -1482,16 +1456,15 @@ int16 Game_v1::inputArea(int16 xPos, int16 yPos, int16 width, int16 height, } } - if (i == (int16)strlen(str1)) + if (i == (int16) strlen(str1)) key = 0; } - if (key >= ' ' && key <= 0xff) { + if ((key >= ' ') && (key <= 0xFF)) { if (editSize == strlen(str)) - _vm->_util->cutFromStr(str, strlen(str) - 1, - 1); + _vm->_util->cutFromStr(str, strlen(str) - 1, 1); - if (key >= 'a' && key <= 'z') + if ((key >= 'a') && (key <= 'z')) key += ('A' - 'a'); pos++; @@ -1499,9 +1472,8 @@ int16 Game_v1::inputArea(int16 xPos, int16 yPos, int16 width, int16 height, _tempStr[1] = 0; _vm->_util->insertStr(_tempStr, str, pos - 1); - - //strupr(str); } + } } } @@ -1518,16 +1490,16 @@ int16 Game_v1::checkMousePoint(int16 all, int16 *resId, int16 *resIndex) { ptr = _collisionAreas; for (i = 0; ptr->left != -1; ptr++, i++) { if (all) { - if ((ptr->flags & 0xf) > 1) + if ((ptr->flags & 0xF) > 1) continue; - if ((ptr->flags & 0xff00) != 0) + if ((ptr->flags & 0xFF00) != 0) continue; - if (_vm->_global->_inter_mouseX < ptr->left - || _vm->_global->_inter_mouseX > ptr->right - || _vm->_global->_inter_mouseY < ptr->top - || _vm->_global->_inter_mouseY > ptr->bottom) + if ((_vm->_global->_inter_mouseX < ptr->left) || + (_vm->_global->_inter_mouseX > ptr->right) || + (_vm->_global->_inter_mouseY < ptr->top) || + (_vm->_global->_inter_mouseY > ptr->bottom)) continue; if (resId != 0) @@ -1536,20 +1508,20 @@ int16 Game_v1::checkMousePoint(int16 all, int16 *resId, int16 *resIndex) { *resIndex = i; return ptr->key; } else { - if ((ptr->flags & 0xff00) != 0) + if ((ptr->flags & 0xFF00) != 0) continue; - if ((ptr->flags & 0xf) != 1 && (ptr->flags & 0xf) != 2) + if (((ptr->flags & 0xF) != 1) && ((ptr->flags & 0xF) != 2)) continue; - if ((ptr->flags & 0xf0) >> 4 != _mouseButtons - 1 - && (ptr->flags & 0xf0) >> 4 != 2) + if ((((ptr->flags & 0xF0) >> 4) != (_mouseButtons - 1)) + && (((ptr->flags & 0xF0) >> 4) != 2)) continue; - if (_vm->_global->_inter_mouseX < ptr->left - || _vm->_global->_inter_mouseX > ptr->right - || _vm->_global->_inter_mouseY < ptr->top - || _vm->_global->_inter_mouseY > ptr->bottom) + if ((_vm->_global->_inter_mouseX < ptr->left) || + (_vm->_global->_inter_mouseX > ptr->right) || + (_vm->_global->_inter_mouseY < ptr->top) || + (_vm->_global->_inter_mouseY > ptr->bottom)) continue; if (resId != 0) @@ -1559,8 +1531,8 @@ int16 Game_v1::checkMousePoint(int16 all, int16 *resId, int16 *resIndex) { } } - if (_mouseButtons != 1 && all == 0) - return 0x11b; + if ((_mouseButtons != 1) && (all == 0)) + return 0x11B; return 0; } diff --git a/engines/gob/game_v2.cpp b/engines/gob/game_v2.cpp index 0f6a62da32..bcd3da4d2f 100644 --- a/engines/gob/game_v2.cpp +++ b/engines/gob/game_v2.cpp @@ -23,22 +23,22 @@ #include "common/stdafx.h" #include "common/endian.h" +#include "common/stream.h" #include "gob/gob.h" -#include "gob/global.h" #include "gob/game.h" -#include "gob/video.h" +#include "gob/global.h" +#include "gob/util.h" #include "gob/dataio.h" -#include "gob/pack.h" -#include "gob/scenery.h" -#include "gob/inter.h" -#include "gob/parse.h" #include "gob/draw.h" -#include "gob/mult.h" -#include "gob/util.h" #include "gob/goblin.h" -#include "gob/cdrom.h" -#include "gob/music.h" +#include "gob/imd.h" +#include "gob/inter.h" +#include "gob/mult.h" +#include "gob/parse.h" +#include "gob/scenery.h" +#include "gob/sound.h" +#include "gob/video.h" namespace Gob { @@ -55,7 +55,6 @@ void Game_v2::playTot(int16 skipPlay) { int16 nestLevel; int32 variablesCount; int32 totSize; - int32 i; char *filePtr; char *savedIP; bool totTextLoc; @@ -78,7 +77,7 @@ void Game_v2::playTot(int16 skipPlay) { if (skipPlay != -1) { _vm->_inter->initControlVars(1); - for (i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { _vm->_draw->_fontToSprite[i].sprite = -1; _vm->_draw->_fontToSprite[i].base = -1; _vm->_draw->_fontToSprite[i].width = -1; @@ -102,7 +101,7 @@ void Game_v2::playTot(int16 skipPlay) { _totToLoad[0] = 0; - if (_curTotFile[0] == 0 && _totFileData == 0) + if ((_curTotFile[0] == 0) && (_totFileData == 0)) break; totSize = loadTotFile(_curTotFile); @@ -127,48 +126,53 @@ void Game_v2::playTot(int16 skipPlay) { debugC(4, kDebugFileIO, "IMA: %s", _curImaFile); debugC(4, kDebugFileIO, "EXT: %s", _curExtFile); - filePtr = (char *)_totFileData + 0x30; + filePtr = (char *) _totFileData + 0x30; _totTextData = 0; totTextLoc = false; - if (READ_LE_UINT32(filePtr) != (uint32)-1) { + if (READ_LE_UINT32(filePtr) != (uint32) -1) { _totTextData = new TotTextTable; if (READ_LE_UINT32(filePtr) == 0) { _totTextData->dataPtr = loadLocTexts(); totTextLoc = true; } else { - _totTextData->dataPtr = (_totFileData + READ_LE_UINT32((char *)_totFileData + 0x30)); + _totTextData->dataPtr = + (_totFileData + READ_LE_UINT32((char *) _totFileData + 0x30)); _vm->_global->_language = _vm->_global->_languageWanted; } _totTextData->items = 0; if (_totTextData->dataPtr != 0) { - Common::MemoryReadStream totTextData((byte *) _totTextData->dataPtr, 4294967295U); + Common::MemoryReadStream totTextData((byte *) _totTextData->dataPtr, + 4294967295U); _totTextData->itemsCount = totTextData.readSint16LE(); _totTextData->items = new TotTextItem[_totTextData->itemsCount]; - for (i = 0; i < _totTextData->itemsCount; ++i) { + for (int i = 0; i < _totTextData->itemsCount; ++i) { _totTextData->items[i].offset = totTextData.readSint16LE(); _totTextData->items[i].size = totTextData.readSint16LE(); } } } - filePtr = (char *)_totFileData + 0x34; + filePtr = (char *) _totFileData + 0x34; _totResourceTable = 0; int32 resSize; - if (READ_LE_UINT32(filePtr) != (uint32)-1) { + if (READ_LE_UINT32(filePtr) != (uint32) -1) { _totResourceTable = new TotResTable; - _totResourceTable->dataPtr = _totFileData + READ_LE_UINT32((char *)_totFileData + 0x34); - Common::MemoryReadStream totResTable((byte *) _totResourceTable->dataPtr, 4294967295U); + _totResourceTable->dataPtr = + _totFileData + READ_LE_UINT32((char *) _totFileData + 0x34); + Common::MemoryReadStream totResTable((byte *) _totResourceTable->dataPtr, + 4294967295U); _totResourceTable->itemsCount = totResTable.readSint16LE(); resSize = _totResourceTable->itemsCount * szGame_TotResItem + szGame_TotResTable; if (totSize > (resSize + 0x34)) { _totResourceTable->unknown = totResTable.readByte(); - _totResourceTable->items = new TotResItem[_totResourceTable->itemsCount]; - for (i = 0; i < _totResourceTable->itemsCount; ++i) { + _totResourceTable->items = + new TotResItem[_totResourceTable->itemsCount]; + for (int i = 0; i < _totResourceTable->itemsCount; ++i) { _totResourceTable->items[i].offset = totResTable.readSint32LE(); _totResourceTable->items[i].size = totResTable.readSint16LE(); _totResourceTable->items[i].width = totResTable.readSint16LE(); @@ -176,10 +180,11 @@ void Game_v2::playTot(int16 skipPlay) { } } else { - // WORKAROUND: In the original asm, _totResourceTable is only assigned - // in playTot and evaluated later, right before using it. In the - // Gobliins 2 demo, there is a dummy tot that loads another tot, overwriting - // the dummy pointer with the real one. + // WORKAROUND: In the original asm, _totResourceTable is + // only assigned in playTot and evaluated later, right + // before using it. In the Gobliins 2 demo, there is a + // dummy tot that loads another tot, overwriting the dummy + // pointer with the real one. debugC(1, kDebugFileIO, "Attempted to load invalid resource table (size = %d, totSize = %d)", resSize, totSize); @@ -191,16 +196,18 @@ void Game_v2::playTot(int16 skipPlay) { loadImFile(); loadExtTable(); - _vm->_global->_inter_animDataSize = READ_LE_UINT16((char *)_totFileData + 0x38); + _vm->_global->_inter_animDataSize = + READ_LE_UINT16((char *) _totFileData + 0x38); if (_vm->_global->_inter_variables == 0) { - variablesCount = READ_LE_UINT16((char *)_totFileData + 0x2c); + variablesCount = READ_LE_UINT16((char *) _totFileData + 0x2C); _vm->_global->_inter_variables = new char[variablesCount * 4]; _vm->_global->_inter_variablesSizes = new byte[variablesCount * 4]; _vm->_global->clearVars(variablesCount); } - _vm->_global->_inter_execPtr = (char *)_totFileData; - _vm->_global->_inter_execPtr += READ_LE_UINT32((char *)_totFileData + 0x64); + _vm->_global->_inter_execPtr = (char *) _totFileData; + _vm->_global->_inter_execPtr += + READ_LE_UINT32((char *) _totFileData + 0x64); _vm->_inter->renewTimeInVars(); @@ -212,16 +219,15 @@ void Game_v2::playTot(int16 skipPlay) { _vm->_inter->callSub(2); if (_totToLoad[0] != 0) - _vm->_inter->_terminate = false; + _vm->_inter->_terminate = 0; - variablesCount = READ_LE_UINT32((char *)_totFileData + 0x2c); + variablesCount = READ_LE_UINT32((char *) _totFileData + 0x2C); _vm->_draw->blitInvalidated(); delete[] _totFileData; _totFileData = 0; if (_totTextData) { - if (_totTextData->items) - delete[] _totTextData->items; + delete[] _totTextData->items; if (totTextLoc) delete[] _totTextData->dataPtr; delete _totTextData; @@ -243,33 +249,24 @@ void Game_v2::playTot(int16 skipPlay) { _extTable = 0; if (_extHandle >= 0) - _vm->_dataio->closeData(_extHandle); + _vm->_dataIO->closeData(_extHandle); _extHandle = -1; - for (i = 0; i < *_vm->_scenery->_pCaptureCounter; i++) + for (int i = 0; i < *_vm->_scenery->_pCaptureCounter; i++) capturePop(0); -/* _vm->_mult->checkFreeMult(); - _vm->_mult->freeAll();*/ - if (skipPlay != -1) { _vm->_goblin->freeObjects(); -/* for (i = 0; i < 50; i++) { - if (_vm->_draw->_spritesArray[i] != 0) - _vm->_video->freeSurfDesc(_vm->_draw->_spritesArray[i]); - _vm->_draw->_spritesArray[i] = 0; - }*/ - _vm->_snd->stopSound(0); - for (i = 0; i < 60; i++) - if ((_soundTypes[i] & 8) == 0) - freeSoundSlot(i); + for (int i = 0; i < 60; i++) + if (_soundSamples[i].getType() == SOUND_SND) + _vm->_snd->freeSample(_soundSamples[i]); } - closeImd(); + _vm->_imdPlayer->closeImd(); if (_totToLoad[0] == 0) break; @@ -278,8 +275,9 @@ void Game_v2::playTot(int16 skipPlay) { } else { _vm->_inter->initControlVars(0); _vm->_scenery->_pCaptureCounter = oldCaptureCounter; - _vm->_global->_inter_execPtr = (char *)_totFileData; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_totFileData + (skipPlay << 1) + 0x66); + _vm->_global->_inter_execPtr = (char *) _totFileData; + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_totFileData + (skipPlay << 1) + 0x66); _vm->_inter->callSub(2); if (_vm->_inter->_terminate != 0) _vm->_inter->_terminate = 2; @@ -294,28 +292,25 @@ void Game_v2::playTot(int16 skipPlay) { } void Game_v2::clearCollisions() { - int16 i; - _lastCollKey = 0; - for (i = 0; i < 150; i++) { -// _collisionAreas[i].id = 0; + for (int i = 0; i < 150; i++) _collisionAreas[i].left = -1; - } } int16 Game_v2::addNewCollision(int16 id, int16 left, int16 top, int16 right, int16 bottom, int16 flags, int16 key, uint16 funcEnter, uint16 funcLeave) { - int16 i; Collision *ptr; debugC(5, kDebugCollisions, "addNewCollision"); - debugC(5, kDebugCollisions, "id = %x", id); - debugC(5, kDebugCollisions, "left = %d, top = %d, right = %d, bottom = %d", left, top, right, bottom); - debugC(5, kDebugCollisions, "flags = %x, key = %x", flags, key); - debugC(5, kDebugCollisions, "funcEnter = %d, funcLeave = %d", funcEnter, funcLeave); - - for (i = 0; i < 150; i++) { + debugC(5, kDebugCollisions, "id = %X", id); + debugC(5, kDebugCollisions, "left = %d, top = %d, right = %d, bottom = %d", + left, top, right, bottom); + debugC(5, kDebugCollisions, "flags = %X, key = %X", flags, key); + debugC(5, kDebugCollisions, "funcEnter = %d, funcLeave = %d", + funcEnter, funcLeave); + + for (int i = 0; i < 150; i++) { if ((_collisionAreas[i].left != -1) && (_collisionAreas[i].id != id)) continue; @@ -329,7 +324,7 @@ int16 Game_v2::addNewCollision(int16 id, int16 left, int16 top, int16 right, int ptr->key = key; ptr->funcEnter = funcEnter; ptr->funcLeave = funcLeave; - ptr->field_12 = 0; + ptr->funcSub = 0; return i; } @@ -394,7 +389,8 @@ void Game_v2::popCollisions(void) { for (destPtr = _collisionAreas; destPtr->left != -1; destPtr++); srcPtr = _collStack[_collStackSize]; - memcpy(destPtr, srcPtr, _collStackElemSizes[_collStackSize] * sizeof(Collision)); + memcpy(destPtr, srcPtr, + _collStackElemSizes[_collStackSize] * sizeof(Collision)); delete[] _collStack[_collStackSize]; } @@ -419,7 +415,8 @@ int16 Game_v2::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, resIndex = 0; - if ((_vm->_draw->_cursorIndex == -1) && (handleMouse != 0) && (_lastCollKey == 0)) { + if ((_vm->_draw->_cursorIndex == -1) && + (handleMouse != 0) && (_lastCollKey == 0)) { _lastCollKey = checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex); if ((_lastCollKey != 0) && (_lastCollId & 0x8000)) @@ -437,7 +434,7 @@ int16 Game_v2::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, return 0; } - if (_vm->_draw->_noInvalidated == 0) { + if (!_vm->_draw->_noInvalidated) { if (handleMouse != 0) _vm->_draw->animateCursor(-1); else @@ -445,92 +442,8 @@ int16 Game_v2::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, _vm->_video->waitRetrace(_vm->_global->_videoMode); } - key = checkKeys(&_vm->_global->_inter_mouseX, &_vm->_global->_inter_mouseY, - &_mouseButtons, handleMouse); - - // TODO: What of this is needed? - // Mouse position calculation in scrollable screen? - int16 width; - int16 height; - int16 sWidth; - int16 sHeight; - int16 cursorRight; - int16 cursorBottom; - int16 oldOffY; - int16 oldOffX; - if ((_vm->_global->_videoMode == 0x14) && (handleMouse != 0)) { - width = _vm->_draw->_frontSurface->width; - height = _vm->_draw->_frontSurface->height; - if ((width > _vm->_global->_primaryWidth) || (height > _vm->_global->_primaryHeight) - || ((_vm->_draw->_off_2E51B != 0) && (height > _vm->_draw->_off_2E51B->height))) { - sWidth = _vm->_global->_primaryWidth; - sHeight = _vm->_global->_primaryHeight; - if (_vm->_draw->_off_2E51B != 0) - sHeight -= _vm->_draw->_off_2E51B->height; - oldOffX = _vm->_draw->_scrollOffsetX; - oldOffY = _vm->_draw->_scrollOffsetY; - if ((width > sWidth) && (_vm->_global->_inter_mouseX >= _vm->_draw->_scrollOffsetX)) { - cursorRight = _vm->_global->_inter_mouseX + _vm->_draw->_cursorWidth; - if (cursorRight > (_vm->_draw->_scrollOffsetX + sWidth)) - _vm->_draw->_scrollOffsetX = MIN(cursorRight - sWidth, width - sWidth); - } else if (_vm->_global->_inter_mouseX < _vm->_draw->_scrollOffsetX) - _vm->_draw->_scrollOffsetX = _vm->_global->_inter_mouseX; - height = _vm->_draw->_frontSurface->height; - if ((height > sHeight) && (_vm->_global->_inter_mouseY >= _vm->_draw->_scrollOffsetY)) { - cursorBottom = _vm->_global->_inter_mouseY + _vm->_draw->_cursorHeight; - if (cursorBottom > (_vm->_draw->_scrollOffsetY + sHeight)) - _vm->_draw->_scrollOffsetY = MIN(cursorBottom - sHeight, height - sHeight); - } else if (_vm->_global->_inter_mouseY < _vm->_draw->_scrollOffsetY) - _vm->_draw->_scrollOffsetY = _vm->_global->_inter_mouseY; - if ((oldOffX != _vm->_draw->_scrollOffsetX) || - (oldOffY != _vm->_draw->_scrollOffsetY)) { - if (_byte_2FC9B == 0) { - _vm->_draw->_scrollOffsetX = oldOffX; - _vm->_draw->_scrollOffsetY = oldOffY; - if ((_vm->_draw->_frontSurface->width > sWidth) && - (_vm->_global->_inter_mouseX >= oldOffX)) { - if ((_vm->_global->_inter_mouseX + _vm->_draw->_cursorWidth) > - (_vm->_draw->_scrollOffsetX + sWidth)) - _vm->_global->_inter_mouseX = _vm->_draw->_scrollOffsetX + - sWidth - _vm->_draw->_cursorWidth; - } else if (_vm->_global->_inter_mouseX < oldOffX) - _vm->_global->_inter_mouseX = oldOffX; - - if ((_vm->_draw->_frontSurface->height > sHeight) && - (_vm->_global->_inter_mouseY >= _vm->_draw->_scrollOffsetY)) { - if ((_vm->_global->_inter_mouseY + _vm->_draw->_cursorHeight) > - (_vm->_draw->_scrollOffsetY + sHeight)) - _vm->_global->_inter_mouseY = _vm->_draw->_scrollOffsetY + - sHeight - _vm->_draw->_cursorHeight; - } else if (_vm->_global->_inter_mouseY < oldOffX) - _vm->_global->_inter_mouseY = _vm->_draw->_scrollOffsetY; - } else { - if (oldOffX > _vm->_draw->_scrollOffsetX) { - _vm->_global->_inter_mouseX += (oldOffX - _vm->_draw->_scrollOffsetX) / 2; - _vm->_draw->_scrollOffsetX += (oldOffX - _vm->_draw->_scrollOffsetX) / 2; - } else { - _vm->_global->_inter_mouseX -= (_vm->_draw->_scrollOffsetX - oldOffX) / 2; - _vm->_draw->_scrollOffsetX -= (_vm->_draw->_scrollOffsetX - oldOffX) / 2; - } - if (oldOffY > _vm->_draw->_scrollOffsetY) { - _vm->_global->_inter_mouseY += (oldOffY - _vm->_draw->_scrollOffsetY) / 2; - _vm->_draw->_scrollOffsetY += (oldOffY - _vm->_draw->_scrollOffsetY) / 2; - if (_vm->_draw->_scrollOffsetY < 2) - _vm->_draw->_scrollOffsetY = 0; - } else { - _vm->_global->_inter_mouseY -= (_vm->_draw->_scrollOffsetY - oldOffY) / 2; - _vm->_draw->_scrollOffsetY -= (_vm->_draw->_scrollOffsetY - oldOffY) / 2; - } - if (_vm->_draw->_off_2E51B == 0) - _vm->_util->setScrollOffset(); - else - _vm->_util->setScrollOffset(_vm->_draw->_scrollOffsetX, - _vm->_draw->_scrollOffsetY + _vm->_draw->_off_2E51B->height); - } - _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY); - } - } - } + key = checkKeys(&_vm->_global->_inter_mouseX, + &_vm->_global->_inter_mouseY, &_mouseButtons, handleMouse); if ((handleMouse == 0) && (_mouseButtons != 0)) { _vm->_util->waitMouseRelease(0); @@ -573,7 +486,8 @@ int16 Game_v2::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, *pResIndex = resIndex; if ((key != 0) || ((pResId != 0) && (*pResId != 0))) { - if ((handleMouse & 1) && ((deltaTime <= 0) || (_mouseButtons == 0))) + if ((handleMouse & 1) && + ((deltaTime <= 0) || (_mouseButtons == 0))) _vm->_draw->blitCursor(); if ((_lastCollKey != 0) && (key != _lastCollKey)) @@ -632,8 +546,6 @@ int16 Game_v2::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, } void Game_v2::prepareStart(void) { - int16 i; - clearCollisions(); _vm->_global->_pPaletteDesc->unused2 = _vm->_draw->_unusedPalette2; @@ -647,29 +559,23 @@ void Game_v2::prepareStart(void) { _vm->_video->_surfWidth - 1, _vm->_video->_surfHeight - 1, 1); _vm->_util->setMousePos(152, 92); + _vm->_draw->_cursorX = _vm->_global->_inter_mouseX = 152; + _vm->_draw->_cursorY = _vm->_global->_inter_mouseY = 92; - _vm->_draw->_cursorX = 152; - _vm->_global->_inter_mouseX = 152; - - _vm->_draw->_cursorY = 92; - _vm->_global->_inter_mouseY = 92; _vm->_draw->_invalidatedCount = 0; - _vm->_draw->_noInvalidated = 1; - // byte_2E521 = 1; - _vm->_draw->_applyPal = 0; - _vm->_draw->_paletteCleared = 0; + _vm->_draw->_noInvalidated = true; + _vm->_draw->_applyPal = false; + _vm->_draw->_paletteCleared = false; _vm->_draw->_cursorWidth = 16; _vm->_draw->_cursorHeight = 16; _vm->_draw->_transparentCursor = 1; - for (i = 0; i < 40; i++) { + for (int i = 0; i < 40; i++) { _vm->_draw->_cursorAnimLow[i] = -1; _vm->_draw->_cursorAnimDelays[i] = 0; _vm->_draw->_cursorAnimHigh[i] = 0; } - // byte_2F392 = 0; - _vm->_draw->_renderFlags = 0; _vm->_draw->_backDeltaX = 0; _vm->_draw->_backDeltaY = 0; @@ -726,9 +632,9 @@ void Game_v2::collisionsBlock(void) { count = *_vm->_global->_inter_execPtr++; _handleMouse = _vm->_global->_inter_execPtr[0]; - deltaTime = 1000 * (byte)_vm->_global->_inter_execPtr[1]; - stackPos2 = (byte)_vm->_global->_inter_execPtr[3]; - descIndex = (byte)_vm->_global->_inter_execPtr[4]; + deltaTime = 1000 * (byte) _vm->_global->_inter_execPtr[1]; + stackPos2 = (byte) _vm->_global->_inter_execPtr[3]; + descIndex = (byte) _vm->_global->_inter_execPtr[4]; if ((stackPos2 != 0) || (descIndex != 0)) deltaTime /= 100; @@ -749,7 +655,7 @@ void Game_v2::collisionsBlock(void) { if ((cmd & 0x40) != 0) { cmd -= 0x40; - cmdHigh = (byte)*_vm->_global->_inter_execPtr; + cmdHigh = (byte) *_vm->_global->_inter_execPtr; _vm->_global->_inter_execPtr++; cmdHigh <<= 8; } else @@ -769,7 +675,7 @@ void Game_v2::collisionsBlock(void) { height = _vm->_inter->load16(); } - if ((_vm->_draw->_renderFlags & 8) && (left != -1)) { + if ((_vm->_draw->_renderFlags & RENDERFLAG_CAPTUREPOP) && (left != -1)) { left += _vm->_draw->_backDeltaX; top += _vm->_draw->_backDeltaY; } @@ -777,14 +683,14 @@ void Game_v2::collisionsBlock(void) { if (left != -1) { _vm->_draw->adjustCoords(0, &left, &top); if (((cmd & 0x3F) < 20) && ((cmd & 0x3F) >= 3)) { - if (_vm->_draw->_word_2E8E2 != 2) + if (_vm->_draw->_needAdjust != 2) height &= 0xFFFE; _vm->_draw->adjustCoords(0, 0, &width); } else _vm->_draw->adjustCoords(0, &height, &width); } - cmd &= 0x7f; + cmd &= 0x7F; debugC(1, kDebugCollisions, "collisionsBlock(%d)", cmd); switch (cmd) { @@ -792,17 +698,20 @@ void Game_v2::collisionsBlock(void) { _vm->_global->_inter_execPtr += 6; startIP = _vm->_global->_inter_execPtr; _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr); key = curCmd + 0xA000; - collId = addNewCollision(curCmd + 0x8000, left, top, left + width - 1, top + height - 1, - cmd + cmdHigh, key, startIP - (char *)_totFileData, - _vm->_global->_inter_execPtr - (char *)_totFileData); + collId = addNewCollision(curCmd + 0x8000, left, top, + left + width - 1, top + height - 1, + cmd + cmdHigh, key, startIP - (char *) _totFileData, + _vm->_global->_inter_execPtr - (char *) _totFileData); _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr); - _collisionAreas[collId].field_12 = offsetIP; + _collisionAreas[collId].funcSub = offsetIP; break; case 1: @@ -812,18 +721,22 @@ void Game_v2::collisionsBlock(void) { startIP = _vm->_global->_inter_execPtr; _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr); + if (key == 0) - key = curCmd + 0xa000; + key = curCmd + 0xA000; - collId = addNewCollision(curCmd + 0x8000, left, top, left + width - 1, top + height - 1, - (flags << 4) + cmd + cmdHigh, key, startIP - (char *)_totFileData, - _vm->_global->_inter_execPtr - (char *)_totFileData); + collId = addNewCollision(curCmd + 0x8000, left, top, + left + width - 1, top + height - 1, + (flags << 4) + cmd + cmdHigh, key, startIP - (char *) _totFileData, + _vm->_global->_inter_execPtr - (char *) _totFileData); _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr); - _collisionAreas[collId].field_12 = offsetIP; + _collisionAreas[collId].funcSub = offsetIP; break; case 3: @@ -834,7 +747,7 @@ void Game_v2::collisionsBlock(void) { case 8: case 9: case 10: - _vm->_util->waitKey(); + _vm->_util->clearKeyBuf(); var_1C = 1; key = _vm->_parse->parseVarIndex(); descArray[index].fontIndex = _vm->_inter->load16(); @@ -843,29 +756,32 @@ void Game_v2::collisionsBlock(void) { if ((cmd >= 5) && (cmd <= 8)) { descArray[index].ptr = _vm->_global->_inter_execPtr + 2; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr) + 2; + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr) + 2; } else descArray[index].ptr = 0; if (left == -1) { if ((cmd & 1) == 0) { _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr); } break; } if ((cmd & 1) == 0) { - addNewCollision(curCmd + 0x8000, left, top, - left + width * _vm->_draw->_fonts[descArray[index].fontIndex]-> itemWidth - 1, + addNewCollision(curCmd + 0x8000, left, top, left + width * + _vm->_draw->_fonts[descArray[index].fontIndex]-> itemWidth - 1, top + height - 1, cmd, key, 0, - _vm->_global->_inter_execPtr - (char *)_totFileData); + _vm->_global->_inter_execPtr - (char *) _totFileData); _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr); } else - addNewCollision(curCmd + 0x8000, left, top, - left + width * _vm->_draw->_fonts[descArray[index].fontIndex]-> itemWidth - 1, + addNewCollision(curCmd + 0x8000, left, top, left + width * + _vm->_draw->_fonts[descArray[index].fontIndex]-> itemWidth - 1, top + height - 1, cmd, key, 0, 0); index++; @@ -876,12 +792,15 @@ void Game_v2::collisionsBlock(void) { for (i = 0; i < 150; i++) { if ((_collisionAreas[i].id & 0xF000) == 0xE000) { _collisionAreas[i].id &= 0xBFFF; - _collisionAreas[i].funcEnter = _vm->_global->_inter_execPtr - (char *) _totFileData; - _collisionAreas[i].funcLeave = _vm->_global->_inter_execPtr - (char *) _totFileData; + _collisionAreas[i].funcEnter = + _vm->_global->_inter_execPtr - (char *) _totFileData; + _collisionAreas[i].funcLeave = + _vm->_global->_inter_execPtr - (char *) _totFileData; } } _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr); break; case 12: @@ -889,12 +808,15 @@ void Game_v2::collisionsBlock(void) { for (i = 0; i < 150; i++) { if ((_collisionAreas[i].id & 0xF000) == 0xD000) { _collisionAreas[i].id &= 0xBFFF; - _collisionAreas[i].funcEnter = _vm->_global->_inter_execPtr - (char *) _totFileData; - _collisionAreas[i].funcLeave = _vm->_global->_inter_execPtr - (char *) _totFileData; + _collisionAreas[i].funcEnter = + _vm->_global->_inter_execPtr - (char *) _totFileData; + _collisionAreas[i].funcLeave = + _vm->_global->_inter_execPtr - (char *) _totFileData; } } _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr); break; case 20: @@ -906,14 +828,16 @@ void Game_v2::collisionsBlock(void) { array[curCmd] = _vm->_inter->load16(); flags = _vm->_inter->load16(); - collId = addNewCollision(curCmd + 0x8000, left, top, left + width - 1, top + height - 1, + collId = addNewCollision(curCmd + 0x8000, left, top, + left + width - 1, top + height - 1, (flags << 4) + cmdHigh + 2, key, 0, - _vm->_global->_inter_execPtr - (char *)_totFileData); + _vm->_global->_inter_execPtr - (char *) _totFileData); _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr); - _collisionAreas[collId].field_12 = offsetIP; + _collisionAreas[collId].funcSub = offsetIP; break; case 21: @@ -921,20 +845,22 @@ void Game_v2::collisionsBlock(void) { array[curCmd] = _vm->_inter->load16(); flags = _vm->_inter->load16() & 3; - collId = addNewCollision(curCmd + 0x8000, left, top, left + width - 1, top + height - 1, + collId = addNewCollision(curCmd + 0x8000, left, top, + left + width - 1, top + height - 1, (flags << 4) + cmdHigh + 2, key, - _vm->_global->_inter_execPtr - (char *)_totFileData, 0); + _vm->_global->_inter_execPtr - (char *) _totFileData, 0); _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr); + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr); - _collisionAreas[collId].field_12 = offsetIP; + _collisionAreas[collId].funcSub = offsetIP; break; } } _forceHandleMouse = 0; - _vm->_util->waitKey(); + _vm->_util->clearKeyBuf(); do { if (var_1C != 0) { @@ -942,7 +868,7 @@ void Game_v2::collisionsBlock(void) { &_activeCollResId, &_activeCollIndex); WRITE_VAR(55, curEditIndex); - if (key == 0x1c0d) { + if (key == 0x1C0D) { for (i = 0; i < 150; i++) { if (_collisionAreas[i].left == -1) break; @@ -953,23 +879,23 @@ void Game_v2::collisionsBlock(void) { if ((_collisionAreas[i].flags & 1) != 0) continue; - if ((_collisionAreas[i].flags & 0x0f) <= 2) + if ((_collisionAreas[i].flags & 0x0F) <= 2) continue; _activeCollResId = _collisionAreas[i].id; - collResId = _collisionAreas[i].id & 0x7fff; + collResId = _collisionAreas[i].id & 0x7FFF; _activeCollIndex = i; break; } break; } } else - key = checkCollisions(_handleMouse, -deltaTime, &_activeCollResId, &_activeCollIndex); + key = checkCollisions(_handleMouse, -deltaTime, + &_activeCollResId, &_activeCollIndex); - if ((key & 0xff) >= ' ' && (key & 0xff) <= 0xff && - (key >> 8) > 1 && (key >> 8) < 12) { - key = '0' + (((key >> 8) - 1) % 10) + (key & 0xff00); - } + if (((key & 0xFF) >= ' ') && ((key & 0xFF) <= 0xFF) && + ((key >> 8) > 1) && ((key >> 8) < 12)) + key = '0' + (((key >> 8) - 1) % 10) + (key & 0xFF00); if (_activeCollResId == 0) { if (key != 0) { @@ -980,7 +906,8 @@ void Game_v2::collisionsBlock(void) { if ((_collisionAreas[i].id & 0xC000) != 0x8000) continue; - if ((_collisionAreas[i].key == key) || (_collisionAreas[i].key == 0x7fff)) { + if ((_collisionAreas[i].key == key) || + (_collisionAreas[i].key == 0x7FFF)) { _activeCollResId = _collisionAreas[i].id; _activeCollIndex = i; break; @@ -995,14 +922,14 @@ void Game_v2::collisionsBlock(void) { if ((_collisionAreas[i].id & 0xC000) != 0x8000) continue; - if ((_collisionAreas[i].key & 0xff00) != 0) + if ((_collisionAreas[i].key & 0xFF00) != 0) continue; if (_collisionAreas[i].key == 0) continue; - if ((adjustKey(key & 0xff) == adjustKey(_collisionAreas[i].key)) || - (_collisionAreas[i].key == 0x7fff)) { + if ((adjustKey(key & 0xFF) == adjustKey(_collisionAreas[i].key)) || + (_collisionAreas[i].key == 0x7FFF)) { _activeCollResId = _collisionAreas[i].id; _activeCollIndex = i; break; @@ -1078,7 +1005,8 @@ void Game_v2::collisionsBlock(void) { break; } } - if ((_lastCollKey != 0) && (_collisionAreas[_lastCollAreaIndex].funcLeave != 0)) + if ((_lastCollKey != 0) && + (_collisionAreas[_lastCollAreaIndex].funcLeave != 0)) collSub(_collisionAreas[_lastCollAreaIndex].funcLeave); _lastCollKey = 0; } @@ -1087,7 +1015,8 @@ void Game_v2::collisionsBlock(void) { } } - if ((_activeCollResId == 0) || (_collisionAreas[_activeCollIndex].funcLeave != 0)) + if ((_activeCollResId == 0) || + (_collisionAreas[_activeCollIndex].funcLeave != 0)) continue; _vm->_inter->storeMouse(); @@ -1102,7 +1031,7 @@ void Game_v2::collisionsBlock(void) { WRITE_VAR(16, 0); _activeCollResId = 0; } - while (_activeCollResId == 0 && !_vm->_inter->_terminate && !_vm->_quitRequested); + while ((_activeCollResId == 0) && !_vm->_inter->_terminate && !_vm->_quitRequested); if ((_activeCollResId & 0xFFF) == collResId) { collStackPos = 0; @@ -1115,32 +1044,30 @@ void Game_v2::collisionsBlock(void) { if ((_collisionAreas[i].id & 0xC000) == 0x8000) continue; - if ((_collisionAreas[i].flags & 0x0f) < 3) + if ((_collisionAreas[i].flags & 0x0F) < 3) continue; - if ((_collisionAreas[i].flags & 0x0f) > 10) + if ((_collisionAreas[i].flags & 0x0F) > 10) continue; - if ((_collisionAreas[i].flags & 0x0f) > 8) { + if ((_collisionAreas[i].flags & 0x0F) > 8) { char *ptr; strcpy(_tempStr, GET_VARO_STR(_collisionAreas[i].key)); - while ((ptr = strchr(_tempStr, ' ')) != 0) { + while ((ptr = strchr(_tempStr, ' '))) _vm->_util->cutFromStr(_tempStr, (ptr - _tempStr), 1); - ptr = strchr(_tempStr, ' '); - } + if (_vm->_language == 2) + while ((ptr = strchr(_tempStr, '.'))) + *ptr = ','; WRITE_VARO_STR(_collisionAreas[i].key, _tempStr); - if (_vm->_language == 2) { // loc_16080 - warning("GOB2 Stub! Game_v2::collisionsBlock(), language == 2"); - } } - if ((_collisionAreas[i].flags & 0x0f) >= 5 && - (_collisionAreas[i].flags & 0x0f) <= 8) { + if (((_collisionAreas[i].flags & 0x0F) >= 5) && + ((_collisionAreas[i].flags & 0x0F) <= 8)) { str = descArray[var_24].ptr; strcpy(_tempStr, GET_VARO_STR(_collisionAreas[i].key)); - if ((_collisionAreas[i].flags & 0x0f) < 7) + if ((_collisionAreas[i].flags & 0x0F) < 7) _vm->_util->prepareStr(_tempStr); int16 pos = 0; @@ -1150,7 +1077,7 @@ void Game_v2::collisionsBlock(void) { str += strlen(str) + 1; - if ((_collisionAreas[i].flags & 0x0f) < 7) + if ((_collisionAreas[i].flags & 0x0F) < 7) _vm->_util->prepareStr(_collStr); if (strcmp(_tempStr, _collStr) == 0) { @@ -1167,7 +1094,7 @@ void Game_v2::collisionsBlock(void) { var_26++; } - if (collStackPos != (int16)VAR(17)) + if (collStackPos != (int16) VAR(17)) WRITE_VAR(17, 0); else WRITE_VAR(17, 1); @@ -1178,7 +1105,8 @@ void Game_v2::collisionsBlock(void) { savedIP = 0; if (!_vm->_inter->_terminate) { - savedIP = (char *)_totFileData + _collisionAreas[_activeCollIndex].funcLeave; + savedIP = (char *) _totFileData + + _collisionAreas[_activeCollIndex].funcLeave; _vm->_inter->storeMouse(); if (VAR(16) == 0) { @@ -1201,15 +1129,15 @@ void Game_v2::collisionsBlock(void) { _vm->_global->_inter_execPtr = savedIP; } -int16 Game_v2::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * inpDesc, - int16 *collResId, int16 *collIndex) { +int16 Game_v2::multiEdit(int16 time, int16 index, int16 *pCurPos, + InputDesc * inpDesc, int16 *collResId, int16 *collIndex) { Collision *collArea; int16 descInd; int16 key; int16 found = -1; int16 i; void *fontExtraBak; - int16 w2E8E2Bak; + int16 needAdjust; descInd = 0; for (i = 0; i < 150; i++) { @@ -1243,8 +1171,8 @@ int16 Game_v2::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * in _vm->_draw->_fontIndex = inpDesc[descInd].fontIndex; fontExtraBak = _vm->_draw->_fonts[_vm->_draw->_fontIndex]->extraData; - w2E8E2Bak = _vm->_draw->_word_2E8E2; - _vm->_draw->_word_2E8E2 = 2; + needAdjust = _vm->_draw->_needAdjust; + _vm->_draw->_needAdjust = 2; _vm->_draw->_fonts[_vm->_draw->_fontIndex]->extraData = 0; _vm->_draw->spriteOperation(DRAW_FILLRECT | 0x10); @@ -1252,7 +1180,7 @@ int16 Game_v2::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * in _vm->_draw->_fonts[_vm->_draw->_fontIndex]->itemHeight) / 2; _vm->_draw->spriteOperation(DRAW_PRINTTEXT | 0x10); - _vm->_draw->_word_2E8E2 = w2E8E2Bak; + _vm->_draw->_needAdjust = needAdjust; _vm->_draw->_fonts[_vm->_draw->_fontIndex]->extraData = fontExtraBak; descInd++; @@ -1307,8 +1235,8 @@ int16 Game_v2::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * in return 0; if (_mouseButtons != 0) { - for (collArea = _collisionAreas, i = 0; collArea->left != -1; collArea++, i++) - { + for (collArea = _collisionAreas, i = 0; + collArea->left != -1; collArea++, i++) { if ((collArea->flags & 0xF00)) continue; @@ -1361,11 +1289,11 @@ int16 Game_v2::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * in } break; - case 0x3b00: - case 0x3c00: - case 0x3d00: - case 0x3e00: - case 0x3f00: + case 0x3B00: + case 0x3C00: + case 0x3D00: + case 0x3E00: + case 0x3F00: case 0x4000: case 0x4100: case 0x4200: @@ -1373,7 +1301,7 @@ int16 Game_v2::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * in case 0x4400: return key; - case 0x1c0d: + case 0x1C0D: if (index == 1) return key; @@ -1414,7 +1342,7 @@ int16 Game_v2::inputArea(int16 xPos, int16 yPos, int16 width, int16 height, int16 flag; int16 savedKey; void *fontExtraBak; - int16 w2E8E2Bak; + int16 needAdjust; if ((_handleMouse != 0) && ((_vm->_global->_useMouse != 0) || (_forceHandleMouse != 0))) @@ -1433,8 +1361,8 @@ int16 Game_v2::inputArea(int16 xPos, int16 yPos, int16 width, int16 height, strcpy(_tempStr, str); fontExtraBak = _vm->_draw->_fonts[fontIndex]->extraData; - w2E8E2Bak = _vm->_draw->_word_2E8E2; - _vm->_draw->_word_2E8E2 = 2; + needAdjust = _vm->_draw->_needAdjust; + _vm->_draw->_needAdjust = 2; _vm->_draw->_fonts[fontIndex]->extraData = 0; _vm->_draw->_destSpriteX = xPos; @@ -1453,7 +1381,7 @@ int16 Game_v2::inputArea(int16 xPos, int16 yPos, int16 width, int16 height, _vm->_draw->_destSpriteY = yPos + (height - pFont->itemHeight) / 2; _vm->_draw->spriteOperation(DRAW_PRINTTEXT | 0x10); - _vm->_draw->_word_2E8E2 = w2E8E2Bak; + _vm->_draw->_needAdjust = needAdjust; _vm->_draw->_fonts[fontIndex]->extraData = fontExtraBak; if (pos == editSize) @@ -1468,8 +1396,8 @@ int16 Game_v2::inputArea(int16 xPos, int16 yPos, int16 width, int16 height, while (1) { fontExtraBak = _vm->_draw->_fonts[fontIndex]->extraData; - w2E8E2Bak = _vm->_draw->_word_2E8E2; - _vm->_draw->_word_2E8E2 = 2; + needAdjust = _vm->_draw->_needAdjust; + _vm->_draw->_needAdjust = 2; _vm->_draw->_fonts[fontIndex]->extraData = 0; _tempStr[0] = curSym; @@ -1483,7 +1411,7 @@ int16 Game_v2::inputArea(int16 xPos, int16 yPos, int16 width, int16 height, _vm->_draw->_backColor = frontColor; _vm->_draw->spriteOperation(DRAW_FILLRECT | 0x10); - _vm->_draw->_word_2E8E2 = w2E8E2Bak; + _vm->_draw->_needAdjust = needAdjust; _vm->_draw->_fonts[fontIndex]->extraData = fontExtraBak; if (flag != 0) { @@ -1495,8 +1423,8 @@ int16 Game_v2::inputArea(int16 xPos, int16 yPos, int16 width, int16 height, key = checkCollisions(handleMouse, -300, collResId, collIndex); fontExtraBak = _vm->_draw->_fonts[fontIndex]->extraData; - w2E8E2Bak = _vm->_draw->_word_2E8E2; - _vm->_draw->_word_2E8E2 = 2; + needAdjust = _vm->_draw->_needAdjust; + _vm->_draw->_needAdjust = 2; _vm->_draw->_fonts[fontIndex]->extraData = 0; _tempStr[0] = curSym; @@ -1516,15 +1444,16 @@ int16 Game_v2::inputArea(int16 xPos, int16 yPos, int16 width, int16 height, _vm->_draw->_destSpriteY = yPos + (height - pFont->itemHeight) / 2; _vm->_draw->spriteOperation(DRAW_PRINTTEXT | 0x10); - _vm->_draw->_word_2E8E2 = w2E8E2Bak; + _vm->_draw->_needAdjust = needAdjust; _vm->_draw->_fonts[fontIndex]->extraData = fontExtraBak; - if (key != 0 || *collResId != 0) + if ((key != 0) || (*collResId != 0)) break; key = checkCollisions(handleMouse, -300, collResId, collIndex); - if ((key != 0) || (*collResId != 0) || _vm->_inter->_terminate || _vm->_quitRequested) + if ((key != 0) || (*collResId != 0) || + _vm->_inter->_terminate || _vm->_quitRequested) break; if (*pTotTime > 0) { @@ -1537,32 +1466,33 @@ int16 Game_v2::inputArea(int16 xPos, int16 yPos, int16 width, int16 height, } } - if ((key == 0) || (*collResId != 0) || _vm->_inter->_terminate || _vm->_quitRequested) + if ((key == 0) || (*collResId != 0) || + _vm->_inter->_terminate || _vm->_quitRequested) return 0; switch (key) { - case 0x4d00: // Right Arrow - if (pos < strlen(str) && pos < editSize - 1) { + case 0x4D00: // Right Arrow + if ((pos < strlen(str)) && (pos < (editSize - 1))) { pos++; continue; } return 0x5000; - case 0x4b00: // Left Arrow + case 0x4B00: // Left Arrow if (pos > 0) { pos--; continue; } return 0x4800; - case 0xe08: // Backspace + case 0xE08: // Backspace if (pos > 0) { _vm->_util->cutFromStr(str, pos - 1, 1); pos--; continue; } - case 0x5300: // Del + case 0x5300: // Del if (pos >= strlen(str)) continue; @@ -1570,29 +1500,29 @@ int16 Game_v2::inputArea(int16 xPos, int16 yPos, int16 width, int16 height, _vm->_util->cutFromStr(str, pos, 1); continue; - case 0x1c0d: // Enter - case 0x3b00: // F1 - case 0x3c00: // F2 - case 0x3d00: // F3 - case 0x3e00: // F4 - case 0x3f00: // F5 - case 0x4000: // F6 - case 0x4100: // F7 - case 0x4200: // F8 - case 0x4300: // F9 - case 0x4400: // F10 - case 0x4800: // Up arrow - case 0x5000: // Down arrow + case 0x1C0D: // Enter + case 0x3B00: // F1 + case 0x3C00: // F2 + case 0x3D00: // F3 + case 0x3E00: // F4 + case 0x3F00: // F5 + case 0x4000: // F6 + case 0x4100: // F7 + case 0x4200: // F8 + case 0x4300: // F9 + case 0x4400: // F10 + case 0x4800: // Up arrow + case 0x5000: // Down arrow return key; - case 0x11b: // Escape + case 0x11B: // Escape if (_vm->_global->_useMouse != 0) continue; _forceHandleMouse = !_forceHandleMouse; - if (_handleMouse != 0 && - (_vm->_global->_useMouse != 0 || _forceHandleMouse != 0)) + if ((_handleMouse != 0) && + ((_vm->_global->_useMouse != 0) || (_forceHandleMouse != 0))) handleMouse = 1; else handleMouse = 0; @@ -1603,15 +1533,16 @@ int16 Game_v2::inputArea(int16 xPos, int16 yPos, int16 width, int16 height, default: savedKey = key; - key &= 0xff; + key &= 0xFF; - if ((inpType == 9 || inpType == 10) && key >= ' ' - && key <= 0xff) { + if (((inpType == 9) || (inpType == 10)) && + (key >= ' ') && (key <= 0xFF)) { str1 = "0123456789-.,+ "; str2 = "0123456789-,,+ "; - if (((savedKey >> 8) > 1 && (savedKey >> 8) < 12) && - ((_vm->_global->_pressedKeys[42] != 0) || (_vm->_global->_pressedKeys[56] != 0))) + if ((((savedKey >> 8) > 1) && ((savedKey >> 8) < 12)) && + ((_vm->_global->_pressedKeys[42] != 0) || + (_vm->_global->_pressedKeys[56] != 0))) key = ((savedKey >> 8) - 1) % 10 + '0'; for (i = 0; str1[i] != 0; i++) { @@ -1621,25 +1552,21 @@ int16 Game_v2::inputArea(int16 xPos, int16 yPos, int16 width, int16 height, } } - if (i == (int16)strlen(str1)) + if (i == (int16) strlen(str1)) key = 0; } - if (key >= ' ' && key <= 0xff) { + if ((key >= ' ') && (key <= 0xFF)) { if (editSize == strlen(str)) _vm->_util->cutFromStr(str, strlen(str) - 1, 1); -/* if (key >= 'a' && key <= 'z') - key += ('A' - 'a');*/ - pos++; _tempStr[0] = key; _tempStr[1] = 0; _vm->_util->insertStr(_tempStr, str, pos - 1); - - //strupr(str); } + } } } @@ -1659,16 +1586,16 @@ int16 Game_v2::checkMousePoint(int16 all, int16 *resId, int16 *resIndex) { continue; if (all) { - if ((ptr->flags & 0xf) > 1) + if ((ptr->flags & 0xF) > 1) continue; - if ((ptr->flags & 0xf00) != 0) + if ((ptr->flags & 0xF00) != 0) continue; - if (_vm->_global->_inter_mouseX < ptr->left - || _vm->_global->_inter_mouseX > ptr->right - || _vm->_global->_inter_mouseY < ptr->top - || _vm->_global->_inter_mouseY > ptr->bottom) + if ((_vm->_global->_inter_mouseX < ptr->left) || + (_vm->_global->_inter_mouseX > ptr->right) || + (_vm->_global->_inter_mouseY < ptr->top) || + (_vm->_global->_inter_mouseY > ptr->bottom)) continue; if (resId != 0) @@ -1677,33 +1604,33 @@ int16 Game_v2::checkMousePoint(int16 all, int16 *resId, int16 *resIndex) { *resIndex = i; return ptr->key; } else { - if ((ptr->flags & 0xf00) != 0) + if ((ptr->flags & 0xF00) != 0) continue; - if ((ptr->flags & 0xf) < 1) + if ((ptr->flags & 0xF) < 1) continue; - if ((ptr->flags & 0xf0) >> 4 != _mouseButtons - 1 - && (ptr->flags & 0xf0) >> 4 != 2) + if ((((ptr->flags & 0xF0) >> 4) != (_mouseButtons - 1)) && + (((ptr->flags & 0xF0) >> 4) != 2)) continue; - if (_vm->_global->_inter_mouseX < ptr->left - || _vm->_global->_inter_mouseX > ptr->right - || _vm->_global->_inter_mouseY < ptr->top - || _vm->_global->_inter_mouseY > ptr->bottom) + if ((_vm->_global->_inter_mouseX < ptr->left) || + (_vm->_global->_inter_mouseX > ptr->right) || + (_vm->_global->_inter_mouseY < ptr->top) || + (_vm->_global->_inter_mouseY > ptr->bottom)) continue; if (resId != 0) *resId = ptr->id; *resIndex = i; - if (((ptr->flags & 0xf) == 1) || ((ptr->flags & 0xf) == 2)) + if (((ptr->flags & 0xF) == 1) || ((ptr->flags & 0xF) == 2)) return ptr->key; return 0; } } - if (_mouseButtons != 1 && all == 0) - return 0x11b; + if ((_mouseButtons != 1) && (all == 0)) + return 0x11B; return 0; } diff --git a/engines/gob/global.cpp b/engines/gob/global.cpp index 5951f65489..9cbc4480b0 100644 --- a/engines/gob/global.cpp +++ b/engines/gob/global.cpp @@ -20,14 +20,15 @@ * $Id$ * */ + #include "gob/gob.h" #include "gob/global.h" namespace Gob { Global::Global(GobEngine *vm) : _vm(vm) { - _useMouse = UNDEF; - _mousePresent = UNDEF; + for (int i = 0; i < 128; i++) + _pressedKeys[i] = 0; _presentCGA = UNDEF; _presentEGA = UNDEF; @@ -36,107 +37,83 @@ Global::Global(GobEngine *vm) : _vm(vm) { _videoMode = 0; _fakeVideoMode = 0; + _oldMode = 3; + + _frameWaitTime = 0; + _startFrameTime = 0; - /* Sound */ _soundFlags = 0; - _blasterPort = 0; - _disableSoundCfg = 0; - /* Mouse */ - _disableMouseCfg = 0; + _language = 0x8000; + _languageWanted = 0x8000; + _useMouse = UNDEF; + _mousePresent = UNDEF; _mouseXShift = 3; _mouseYShift = 3; - _mouseMaxCol = 320; _mouseMaxRow = 200; - /* Language */ - _disableLangCfg = 0x8000; - _language = 0x8000; - _languageWanted = 0x8000; - - /* Timer variables */ - _startTime = 0; - _timer_delta = 1000; - - _frameWaitTime = 0; - _startFrameTime = 0; - - /* Timer and delays */ - _delayTime = 0; - - /* Joystick */ _useJoystick = 1; - /* Data files */ - _packedSize = 0; - int i; - - for (i = 0; i < MAX_DATA_FILES; i++) { - _dataFiles[i] = 0; - _numDataChunks[i] = 0; - _dataFileHandles[i] = -1; - } - _primaryWidth = 0; _primaryHeight = 0; - _sprAllocated = 0; - - _doRangeClamp = 0; + _colorCount = 16; + for (int i = 0; i < 256; i++) { + _redPalette[i] = 0; + _greenPalette[i] = 0; + _bluePalette[i] = 0; + } - _setAllPalette = 0; + _unusedPalette1[ 0] = (int16) 0x0000; + _unusedPalette1[ 1] = (int16) 0x000B; + _unusedPalette1[ 2] = (int16) 0x0000; + _unusedPalette1[ 3] = (int16) 0x5555; + _unusedPalette1[ 4] = (int16) 0xAAAA; + _unusedPalette1[ 5] = (int16) 0xFFFF; + _unusedPalette1[ 6] = (int16) 0x0000; + _unusedPalette1[ 7] = (int16) 0x5555; + _unusedPalette1[ 8] = (int16) 0xAAAA; + _unusedPalette1[ 9] = (int16) 0xFFFF; + _unusedPalette1[10] = (int16) 0x0000; + _unusedPalette1[11] = (int16) 0x5555; + _unusedPalette1[12] = (int16) 0xAAAA; + _unusedPalette1[13] = (int16) 0xFFFF; + _unusedPalette1[14] = (int16) 0x0000; + _unusedPalette1[15] = (int16) 0x5555; + _unusedPalette1[16] = (int16) 0xAAAA; + _unusedPalette1[17] = (int16) 0xFFFF; + + for (int i = 0; i < 16 ;i++) + _unusedPalette2[i] = i; - _oldMode = 3; - _dontSetPalette = 0; - _primarySurfDesc.vidPtr = 0; - _pPrimarySurfDesc = 0; + _vgaPalette[ 0].red = 0x00; _vgaPalette[ 0].green = 0x00; _vgaPalette[ 0].blue = 0x00; + _vgaPalette[ 1].red = 0x00; _vgaPalette[ 1].green = 0x00; _vgaPalette[ 1].blue = 0x2A; + _vgaPalette[ 2].red = 0x00; _vgaPalette[ 2].green = 0x2A; _vgaPalette[ 2].blue = 0x00; + _vgaPalette[ 3].red = 0x00; _vgaPalette[ 3].green = 0x2A; _vgaPalette[ 3].blue = 0x2A; + _vgaPalette[ 4].red = 0x2A; _vgaPalette[ 4].green = 0x00; _vgaPalette[ 4].blue = 0x00; + _vgaPalette[ 5].red = 0x2A; _vgaPalette[ 5].green = 0x00; _vgaPalette[ 5].blue = 0x2A; + _vgaPalette[ 6].red = 0x2A; _vgaPalette[ 6].green = 0x15; _vgaPalette[ 6].blue = 0x00; + _vgaPalette[ 7].red = 0x2A; _vgaPalette[ 7].green = 0x2A; _vgaPalette[ 7].blue = 0x2A; + _vgaPalette[ 8].red = 0x15; _vgaPalette[ 8].green = 0x15; _vgaPalette[ 8].blue = 0x15; + _vgaPalette[ 9].red = 0x15; _vgaPalette[ 9].green = 0x15; _vgaPalette[ 9].blue = 0x3F; + _vgaPalette[10].red = 0x15; _vgaPalette[10].green = 0x3F; _vgaPalette[10].blue = 0x15; + _vgaPalette[11].red = 0x15; _vgaPalette[11].green = 0x3F; _vgaPalette[11].blue = 0x3F; + _vgaPalette[12].red = 0x3F; _vgaPalette[12].green = 0x15; _vgaPalette[12].blue = 0x15; + _vgaPalette[13].red = 0x3F; _vgaPalette[13].green = 0x15; _vgaPalette[13].blue = 0x3F; + _vgaPalette[14].red = 0x3F; _vgaPalette[14].green = 0x3F; _vgaPalette[14].blue = 0x15; + _vgaPalette[15].red = 0x3F; _vgaPalette[15].green = 0x3F; _vgaPalette[15].blue = 0x3F; _pPaletteDesc = 0; - _unusedPalette1[0] = (int16)0; - _unusedPalette1[1] = (int16)0x0b; - _unusedPalette1[2] = (int16)0; - _unusedPalette1[3] = (int16)0x5555; - _unusedPalette1[4] = (int16)0xAAAA; - _unusedPalette1[5] = (int16)0xFFFF; - _unusedPalette1[6] = (int16)0; - _unusedPalette1[7] = (int16)0x5555; - _unusedPalette1[8] = (int16)0xAAAA; - _unusedPalette1[9] = (int16)0xFFFF; - _unusedPalette1[10] = (int16)0; - _unusedPalette1[11] = (int16)0x5555; - _unusedPalette1[12] = (int16)0xAAAA; - _unusedPalette1[13] = (int16)0xFFFF; - _unusedPalette1[14] = (int16)0; - _unusedPalette1[15] = (int16)0x5555; - _unusedPalette1[16] = (int16)0xAAAA; - _unusedPalette1[17] = (int16)0xFFFF; - - for (i = 0; i < 16 ;i++) - _unusedPalette2[i] = i; + _setAllPalette = false; + _dontSetPalette = false; - _vgaPalette[0].red = 0x00; _vgaPalette[0].green = 0x00; _vgaPalette[0].blue = 0x00; - _vgaPalette[1].red = 0x00; _vgaPalette[1].green = 0x00; _vgaPalette[1].blue = 0x2a; - _vgaPalette[2].red = 0x00; _vgaPalette[2].green = 0x2a; _vgaPalette[2].blue = 0x00; - _vgaPalette[3].red = 0x00; _vgaPalette[3].green = 0x2a; _vgaPalette[3].blue = 0x2a; - _vgaPalette[4].red = 0x2a; _vgaPalette[4].green = 0x00; _vgaPalette[4].blue = 0x00; - _vgaPalette[5].red = 0x2a; _vgaPalette[5].green = 0x00; _vgaPalette[5].blue = 0x2a; - _vgaPalette[6].red = 0x2a; _vgaPalette[6].green = 0x15; _vgaPalette[6].blue = 0x00; - _vgaPalette[7].red = 0x2a; _vgaPalette[7].green = 0x2a; _vgaPalette[7].blue = 0x2a; - _vgaPalette[8].red = 0x15; _vgaPalette[8].green = 0x15; _vgaPalette[8].blue = 0x15; - _vgaPalette[9].red = 0x15; _vgaPalette[9].green = 0x15; _vgaPalette[9].blue = 0x3f; - _vgaPalette[10].red = 0x15; _vgaPalette[10].green = 0x3f; _vgaPalette[10].blue = 0x15; - _vgaPalette[11].red = 0x15; _vgaPalette[11].green = 0x3f; _vgaPalette[11].blue = 0x3f; - _vgaPalette[12].red = 0x3f; _vgaPalette[12].green = 0x15; _vgaPalette[12].blue = 0x15; - _vgaPalette[13].red = 0x3f; _vgaPalette[13].green = 0x15; _vgaPalette[13].blue = 0x3f; - _vgaPalette[14].red = 0x3f; _vgaPalette[14].green = 0x3f; _vgaPalette[14].blue = 0x15; - _vgaPalette[15].red = 0x3f; _vgaPalette[15].green = 0x3f; _vgaPalette[15].blue = 0x3f; + _primarySurfDesc = new SurfaceDesc(0x13, 320, 200); _debugFlag = 0; _inVM = 0; - _colorCount = 16; _inter_resStr[0] = 0; _inter_resVal = 0; @@ -149,16 +126,11 @@ Global::Global(GobEngine *vm) : _vm(vm) { _inter_mouseX = 0; _inter_mouseY = 0; - for (i = 0; i < 128; i++) - _pressedKeys[i] = 0; - _savedBack = 0; _savedBackSize = -1; } Global::~Global() { - if (_primarySurfDesc.vidPtr) - delete[] _primarySurfDesc.vidPtr; } } // End of namespace Gob diff --git a/engines/gob/global.h b/engines/gob/global.h index 742863e705..fb455a426c 100644 --- a/engines/gob/global.h +++ b/engines/gob/global.h @@ -20,18 +20,18 @@ * $Id$ * */ + #ifndef GOB_GLOBAL_H #define GOB_GLOBAL_H -#include "gob/dataio.h" -#include "gob/video.h" - #include "common/file.h" +#include "gob/video.h" + namespace Gob { #define VIDMODE_CGA 0x05 -#define VIDMODE_EGA 0x0d +#define VIDMODE_EGA 0x0D #define VIDMODE_VGA 0x13 #define VIDMODE_HER 7 @@ -46,14 +46,14 @@ namespace Gob { #define YES 1 #define UNDEF 2 -#define F1_KEY 0x3b00 -#define F2_KEY 0x3c00 -#define F3_KEY 0x3d00 -#define F4_KEY 0x3e00 -#define F5_KEY 0x3f00 +#define F1_KEY 0x3B00 +#define F2_KEY 0x3C00 +#define F3_KEY 0x3D00 +#define F4_KEY 0x3E00 +#define F5_KEY 0x3F00 #define F6_KEY 0x4000 -#define ESCAPE 0x001b -#define ENTER 0x000d +#define ESCAPE 0x001B +#define ENTER 0x000D #define MAX_FILES 30 @@ -68,9 +68,6 @@ class Global { public: char _pressedKeys[128]; - char _useMouse; - int16 _mousePresent; - int16 _presentCGA; int16 _presentEGA; int16 _presentVGA; @@ -78,80 +75,48 @@ public: int16 _videoMode; int16 _fakeVideoMode; + int16 _oldMode; - int16 _disableVideoCfg; + int16 _frameWaitTime; + int32 _startFrameTime; uint16 _soundFlags; - int16 _disableSoundCfg; - int16 _blasterPort; - uint16 _disableLangCfg; uint16 _language; uint16 _languageWanted; - // Timer variables - int32 _startTime; - int16 _timer_delta; - - int16 _frameWaitTime; - int32 _startFrameTime; - - // Mouse - int16 _disableMouseCfg; - + char _useMouse; + int16 _mousePresent; int16 _mouseXShift; int16 _mouseYShift; int16 _mouseMaxCol; int16 _mouseMaxRow; - // Timer and delays - int16 _delayTime; - - // Joystick char _useJoystick; - // Files Common::File _filesHandles[MAX_FILES]; - // Data files - struct DataIO::ChunkDesc *_dataFiles[MAX_DATA_FILES]; - int16 _numDataChunks[MAX_DATA_FILES]; - int16 _dataFileHandles[MAX_DATA_FILES]; - int32 _chunkPos[MAX_SLOT_COUNT * MAX_DATA_FILES]; - int32 _chunkOffset[MAX_SLOT_COUNT * MAX_DATA_FILES]; - int32 _chunkSize[MAX_SLOT_COUNT * MAX_DATA_FILES]; - char _isCurrentSlot[MAX_SLOT_COUNT * MAX_DATA_FILES]; - int32 _packedSize; - - int16 _sprAllocated; - int16 _primaryWidth; int16 _primaryHeight; - int16 _doRangeClamp; - + int16 _colorCount; char _redPalette[256]; char _greenPalette[256]; char _bluePalette[256]; - int16 _setAllPalette; - - Video::SurfaceDesc _primarySurfDesc; - Video::SurfaceDesc *_pPrimarySurfDesc; - - int16 _oldMode; - char _dontSetPalette; - - Video::PalDesc *_pPaletteDesc; - int16 _unusedPalette1[18]; int16 _unusedPalette2[16]; Video::Color _vgaPalette[16]; Video::PalDesc _paletteStruct; + Video::PalDesc *_pPaletteDesc; + + bool _setAllPalette; + bool _dontSetPalette; + + SurfaceDesc::Ptr _primarySurfDesc; int16 _debugFlag; int16 _inVM; - int16 _colorCount; char _inter_resStr[200]; int32 _inter_resVal; @@ -167,27 +132,21 @@ public: // While using the notepad or changing the font, the original executable // temporarily dumps Draw::_backSurface to a file. Since that's not really // a nice thing to do, we work around it. - Video::SurfaceDesc *_savedBack; + SurfaceDesc::Ptr _savedBack; Video::Color _savedPal[256]; int32 _savedBackSize; - inline void clearVars(uint32 count) + void clearVars(uint32 count) { - uint32 i; + uint32 size = count * 4; - for (i = 0; i < count; i++) { - _inter_variablesSizes[i * 4] = 3; - _inter_variablesSizes[i * 4 + 1] = 0; - _inter_variablesSizes[i * 4 + 2] = 0; - _inter_variablesSizes[i * 4 + 3] = 0; - _inter_variables[i * 4] = 0; - _inter_variables[i * 4 + 1] = 0; - _inter_variables[i * 4 + 2] = 0; - _inter_variables[i * 4 + 3] = 0; - } + memset(_inter_variables, 0, size); + memset(_inter_variablesSizes, 0, size); + for (uint32 i = 0; i < size; i += 4) + _inter_variablesSizes[i] = 3; } - inline void writeVarSizeStr(uint32 offset, uint32 len) { + void writeVarSizeStr(uint32 offset, uint32 len) { uint32 i; uint32 inVar; uint32 varOff; @@ -203,19 +162,19 @@ public: memset(_inter_variablesSizes + offset, 0, len); } - inline void writeVar(uint32 offset, uint32 val) { + void writeVar(uint32 offset, uint32 val) { (*(uint32 *)(_inter_variables + offset)) = val; writeVarSize(offset, 3); } - inline void writeVar(uint32 offset, uint16 val) { + void writeVar(uint32 offset, uint16 val) { (*(uint16 *)(_inter_variables + offset)) = val; writeVarSize(offset, 1); } - inline void writeVar(uint32 offset, uint8 val) { + void writeVar(uint32 offset, uint8 val) { (*(uint8 *)(_inter_variables + offset)) = val; writeVarSize(offset, 0); } - inline void writeVar(uint32 offset, const char *str) { + void writeVar(uint32 offset, const char *str) { writeVarSizeStr(offset, strlen(str)); strcpy(_inter_variables + offset, str); } @@ -226,7 +185,7 @@ public: protected: GobEngine *_vm; - inline void writeVarSize(uint32 offset, byte n) { + void writeVarSize(uint32 offset, byte n) { uint32 i; uint32 inVar; uint32 varOff; @@ -249,4 +208,4 @@ protected: } // End of namespace Gob -#endif +#endif // GOB_GLOBAL_H diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index 9bc29c49a2..81d61e3734 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -19,6 +19,7 @@ * $Id$ * */ + #include "common/stdafx.h" #include "common/endian.h" @@ -26,29 +27,26 @@ #include "common/config-manager.h" #include "common/fs.h" #include "common/md5.h" +#include "sound/mididrv.h" #include "gob/gob.h" - #include "gob/global.h" +#include "gob/util.h" +#include "gob/dataio.h" #include "gob/game.h" #include "gob/sound.h" #include "gob/init.h" #include "gob/inter.h" #include "gob/draw.h" -#include "gob/anim.h" #include "gob/cdrom.h" #include "gob/goblin.h" #include "gob/map.h" #include "gob/mult.h" -#include "gob/pack.h" #include "gob/palanim.h" #include "gob/parse.h" #include "gob/scenery.h" -#include "gob/timer.h" -#include "gob/util.h" #include "gob/music.h" - -#include "sound/mididrv.h" +#include "gob/imd.h" // Use the original saves. Just for testing purposes, will be removed later // The new method is more convenient, and, more importantly, endian-safe @@ -56,9 +54,20 @@ namespace Gob { - #define MAX_TIME_DELTA 100 +const Common::Language GobEngine::_gobToScummVMLang[] = { + Common::FR_FRA, + Common::DE_DEU, + Common::EN_GRB, + Common::ES_ESP, + Common::IT_ITA, + Common::EN_USA, + Common::NL_NLD, + Common::KO_KOR, + Common::HB_ISR +}; + GobEngine::GobEngine(OSystem *syst) : Engine(syst) { // Setup mixer if (!_mixer->isReady()) { @@ -98,31 +107,28 @@ GobEngine::~GobEngine() { // Stop all mixer streams (except for the permanent ones). _vm->_mixer->stopAll(); + delete _snd; + delete _adlib; delete _mult; delete _game; - delete _snd; delete _global; - delete _draw; - delete _anim; delete _cdrom; - delete _dataio; + delete _dataIO; delete _goblin; + delete _imdPlayer; delete _init; delete _inter; delete _map; - delete _pack; - delete _palanim; + delete _palAnim; delete _parse; delete _scenery; - delete _gtimer; + delete _draw; delete _util; - delete _adlib; delete _video; delete[] _startTot; delete[] _startTot0; - int i; - for (i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) delete[] _saveFiles[i]; delete[] _saveFiles; delete[] _saveSlotFile; @@ -186,7 +192,7 @@ void GobEngine::saveGameData(enum SaveFiles sFile, int16 dataVar, int32 size, in int32 iSize; int32 oSize; int32 oOff; - Video::SurfaceDesc *srcDesc; + SurfaceDesc *srcDesc; Common::InSaveFile *in; Common::OutSaveFile *out; @@ -217,13 +223,10 @@ void GobEngine::saveGameData(enum SaveFiles sFile, int16 dataVar, int32 size, in } srcDesc = _draw->_spritesArray[index]; - if (_global->_savedBack) - _video->freeSurfDesc(_global->_savedBack); - _global->_savedBack = - _video->initSurfDesc(_vm->_global->_videoMode, srcDesc->width, srcDesc->height, 0); + _video->initSurfDesc(_vm->_global->_videoMode, srcDesc->getWidth(), srcDesc->getHeight(), 0); _vm->_video->drawSprite(srcDesc, _global->_savedBack, 0, 0, - srcDesc->width - 1, srcDesc->height - 1, 0, 0, 0); + srcDesc->getWidth() - 1, srcDesc->getHeight() - 1, 0, 0, 0); _global->_savedBackSize = _draw->getSpriteRectSize(index); if (writePal) @@ -247,7 +250,7 @@ void GobEngine::saveGameData(enum SaveFiles sFile, int16 dataVar, int32 size, in buf = _global->_inter_variables + dataVar; #ifndef GOB_ORIGSAVES if (sFile == SAVE_CAT) { - if(saveGame((offset - 600) / varSize, dataVar, size, offset)) + if (saveGame((offset - 600) / varSize, dataVar, size, offset)) WRITE_VAR(1, 0); return; } else if (offset != 0) { @@ -271,7 +274,7 @@ void GobEngine::saveGameData(enum SaveFiles sFile, int16 dataVar, int32 size, in delete in; } - if(!(out = _saveFileMan->openForSaving(sName))) { + if (!(out = _saveFileMan->openForSaving(sName))) { warning("Can't open file \"%s\" for writing", sName); delete[] oBuf; return; @@ -306,7 +309,7 @@ bool GobEngine::saveGame(int saveSlot, int16 dataVar, int32 size, int32 offset) memcpy(_saveIndex, varBuf, size); memcpy(_saveIndexSizes, sizeBuf, size); return true; - } else if((((offset - 600) % varSize) == 0) && (size == varSize)) { + } else if ((((offset - 600) % varSize) == 0) && (size == varSize)) { if (!(out = _saveFileMan->openForSaving(getSaveSlotFile(saveSlot)))) { warning("Can't open file \"%s\" for writing", getSaveSlotFile(saveSlot)); return false; @@ -372,7 +375,7 @@ void GobEngine::loadGameData(enum SaveFiles sFile, int16 dataVar, int32 size, in char *buf; char *sName; bool readPal; - Video::SurfaceDesc *destDesc; + SurfaceDesc *destDesc; Common::InSaveFile *in; index = 0; @@ -398,17 +401,17 @@ void GobEngine::loadGameData(enum SaveFiles sFile, int16 dataVar, int32 size, in } destDesc = _draw->_spritesArray[index]; - if ((destDesc->width != _global->_savedBack->width) || - (destDesc->height != _global->_savedBack->height)) { + if ((destDesc->getWidth() != _global->_savedBack->getWidth()) || + (destDesc->getHeight() != _global->_savedBack->getHeight())) { warning("Resolution doesn't match while loading a sprite"); return; } _vm->_video->drawSprite(_global->_savedBack, destDesc, 0, 0, - destDesc->width - 1, destDesc->height - 1, 0, 0, 0); + destDesc->getWidth() - 1, destDesc->getHeight() - 1, 0, 0, 0); if (index == 21) { _video->drawSprite(_draw->_backSurface, _draw->_frontSurface, 0, 0, - _draw->_frontSurface->width - 1, _draw->_frontSurface->height - 1, 0, 0, 0); + _draw->_frontSurface->getWidth() - 1, _draw->_frontSurface->getHeight() - 1, 0, 0, 0); _video->waitRetrace(_global->_videoMode); } @@ -430,7 +433,7 @@ void GobEngine::loadGameData(enum SaveFiles sFile, int16 dataVar, int32 size, in buf = _global->_inter_variables + dataVar; #ifndef GOB_ORIGSAVES if (sFile == SAVE_CAT) { - if(loadGame((offset - 600) / varSize, dataVar, size, offset)) + if (loadGame((offset - 600) / varSize, dataVar, size, offset)) WRITE_VAR(1, 0); return; } else if (offset != 0) { @@ -444,7 +447,7 @@ void GobEngine::loadGameData(enum SaveFiles sFile, int16 dataVar, int32 size, in return; } - if(!(in = _saveFileMan->openForLoading(sName))) { + if (!(in = _saveFileMan->openForLoading(sName))) { warning("Can't open file \"%s\" for reading", sName); return; } @@ -487,7 +490,7 @@ bool GobEngine::loadGame(int saveSlot, int16 dataVar, int32 size, int32 offset) memset(varBuf, 0, 40); } return true; - } else if((((offset - 600) % varSize) == 0) && (size == varSize)) { + } else if ((((offset - 600) % varSize) == 0) && (size == varSize)) { if (!(in = _saveFileMan->openForLoading(getSaveSlotFile(saveSlot)))) { warning("Can't load from slot %d", saveSlot); return false; @@ -554,6 +557,20 @@ uint32 GobEngine::readDataEndian(Common::InSaveFile &in, char *varBuf, byte *siz #endif // GOB_ORIGSAVES } +void GobEngine::validateLanguage() { + if (_vm->_global->_languageWanted != _vm->_global->_language) { + warning("Your game version doesn't support the requested language"); + warning("Using the first language available: %s", + getLangDesc(_vm->_global->_language)); + _vm->_global->_languageWanted = _vm->_global->_language; + } +} + +void GobEngine::validateVideoMode(int16 videoMode) { + if ((videoMode != 0x13) && (videoMode != 0x14)) + error("Video mode 0x%X is not supported!", videoMode); +} + int GobEngine::init() { // Detect game if (!detectGame()) { @@ -562,52 +579,47 @@ int GobEngine::init() { } _adlib = 0; - _snd = new Snd(this); _global = new Global(this); - _anim = new Anim(); - _cdrom = new CDROM(this); - _dataio = new DataIO(this); - _pack = new Pack(); - _palanim = new PalAnim(this); - _gtimer = new GTimer(); _util = new Util(this); + _dataIO = new DataIO(this); + _palAnim = new PalAnim(this); + _imdPlayer = new ImdPlayer(this); + _cdrom = new CDROM(this); + _snd = new Snd(this); if (_features & Gob::GF_GOB1) { + _init = new Init_v1(this); + _video = new Video_v1(this); _inter = new Inter_v1(this); _parse = new Parse_v1(this); _mult = new Mult_v1(this); _draw = new Draw_v1(this); _game = new Game_v1(this); - _video = new Video_v1(this); - _init = new Init_v1(this); _map = new Map_v1(this); _goblin = new Goblin_v1(this); _scenery = new Scenery_v1(this); - } - else if (_features & Gob::GF_GOB2) { + } else if (_features & Gob::GF_GOB2) { + _init = new Init_v2(this); + _video = new Video_v2(this); _inter = new Inter_v2(this); _parse = new Parse_v2(this); _mult = new Mult_v2(this); _draw = new Draw_v2(this); _game = new Game_v2(this); - _video = new Video_v2(this); - _init = new Init_v2(this); _map = new Map_v2(this); _goblin = new Goblin_v2(this); _scenery = new Scenery_v2(this); - } - else if (_features & Gob::GF_BARGON) { + } else if (_features & Gob::GF_BARGON) { + _init = new Init_v2(this); + _video = new Video_v2(this); _inter = new Inter_Bargon(this); _parse = new Parse_v2(this); _mult = new Mult_v2(this); _draw = new Draw_Bargon(this); _game = new Game_v2(this); - _video = new Video_v2(this); - _init = new Init_v2(this); _map = new Map_v2(this); _goblin = new Goblin_v2(this); _scenery = new Scenery_v2(this); - } - else + } else error("GobEngine::init(): Unknown version of game engine"); _noMusic = MidiDriver::parseMusicDriver(ConfMan.get("music_driver")) == MD_NULL; @@ -634,7 +646,7 @@ int GobEngine::init() { _system->openCD(cd_num); _global->_debugFlag = 1; - _global->_doRangeClamp = 1; + _video->_doRangeClamp = true; // WORKAROUND: Some versions check the video mode to detect the system if (_platform == Common::kPlatformAmiga) diff --git a/engines/gob/gob.h b/engines/gob/gob.h index 3538390875..6f64053fe6 100644 --- a/engines/gob/gob.h +++ b/engines/gob/gob.h @@ -36,31 +36,20 @@ class Snd; class Video; class Global; class Draw; -class Anim; class CDROM; class DataIO; class Goblin; +class ImdPlayer; class Init; class Inter; class Map; class Mult; -class Pack; class PalAnim; class Parse; class Scenery; -class GTimer; class Util; class Adlib; -/* -#define VAR_OFFSET(offs) (*(uint32 *)(_vm->_global->_inter_variables + (offs))) -#define VAR(var) VAR_OFFSET((var) << 2) -#define VAR_ADDRESS(var) (&VAR(var)) - -#define WRITE_VAR_OFFSET(offs, val) (VAR_OFFSET(offs) = (val)) -#define WRITE_VAR(var, val) WRITE_VAR_OFFSET((var) << 2, (val)) -*/ - #define VARP(offs) (_vm->_global->_inter_variables + (offs)) #define WRITE_VARO_UINT32(offs, val) _vm->_global->writeVar(offs, (uint32) (val)) #define WRITE_VARO_UINT16(offs, val) _vm->_global->writeVar(offs, (uint16) (val)) @@ -114,12 +103,62 @@ enum SaveFiles { SAVE_BLO // Notes }; +// A "smart" reference counting templated class +template<typename T> +class ReferenceCounter { +public: + class Ptr { + public: + T* operator-> () { return _p; } + T& operator* () { return *_p; } + operator T*() { return _p; } + + Ptr(T* p) : _p(p) { ++_p->_references; } + Ptr() : _p(0) { } + + ~Ptr() { + if (_p && (--_p->_references == 0)) + delete _p; + } + + Ptr(const Ptr& p) : _p(p._p) { ++_p->_references; } + + 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) { + if (p) + ++p->_p->_references; + if (_p && (--_p->_references == 0)) + delete _p; + + _p = p ? p->_p : 0; + return this; + } + + private: + T* _p; + }; + + ReferenceCounter() : _references(0) { } + virtual ~ReferenceCounter() {} + +private: + unsigned _references; + friend class Ptr; +}; + class GobEngine : public Engine { protected: char **_saveFiles; char *_saveSlotFile; char _saveIndex[600]; byte _saveIndexSizes[600]; + GobEngine *_vm; int go(); int init(); @@ -133,10 +172,7 @@ protected: bool detectGame(); public: - GobEngine(OSystem *syst); - virtual ~GobEngine(); - - void shutdown(); + static const Common::Language _gobToScummVMLang[]; Common::RandomSource _rnd; @@ -149,34 +185,42 @@ public: bool _noMusic; bool _quitRequested; + Global *_global; + Util *_util; + DataIO *_dataIO; Game *_game; Snd *_snd; Video *_video; - Global *_global; Draw *_draw; - Anim *_anim; CDROM *_cdrom; - DataIO *_dataio; Goblin *_goblin; Init *_init; Map *_map; Mult *_mult; - Pack *_pack; - PalAnim *_palanim; + PalAnim *_palAnim; Parse *_parse; Scenery *_scenery; - GTimer *_gtimer; - Util *_util; Inter *_inter; Adlib *_adlib; - GobEngine *_vm; + ImdPlayer *_imdPlayer; - void writeVarDebug(uint32 offs, uint32 v); + void shutdown(); int32 getSaveSize(enum SaveFiles sFile); void saveGameData(enum SaveFiles sFile, int16 dataVar, int32 size, int32 offset); void loadGameData(enum SaveFiles sFile, int16 dataVar, int32 size, int32 offset); + const char *getLangDesc(int16 language) { + if ((language < 0) || (language > 8)) + language = 2; + return Common::getLanguageDescription(_gobToScummVMLang[language]); + } + void validateLanguage(); + void validateVideoMode(int16 videoMode); + + GobEngine(OSystem *syst); + virtual ~GobEngine(); }; } // End of namespace Gob -#endif + +#endif // GOB_GOB_H diff --git a/engines/gob/goblin.cpp b/engines/gob/goblin.cpp index afbcf83ae6..71b2a7704b 100644 --- a/engines/gob/goblin.cpp +++ b/engines/gob/goblin.cpp @@ -20,27 +20,21 @@ * $Id$ * */ + #include "gob/gob.h" #include "gob/goblin.h" -#include "gob/inter.h" #include "gob/global.h" +#include "gob/util.h" #include "gob/draw.h" -#include "gob/video.h" -#include "gob/anim.h" -#include "gob/scenery.h" -#include "gob/map.h" -#include "gob/sound.h" #include "gob/game.h" -#include "gob/dataio.h" -#include "gob/cdrom.h" -#include "gob/music.h" +#include "gob/map.h" #include "gob/mult.h" +#include "gob/scenery.h" +#include "gob/sound.h" namespace Gob { Goblin::Goblin(GobEngine *vm) : _vm(vm) { - int i; - _goesAtTarget = 0; _readyToAct = 0; _gobAction = 0; @@ -67,15 +61,14 @@ Goblin::Goblin(GobEngine *vm) : _vm(vm) { _noPick = 0; _objList = 0; - for (i = 0; i < 4; i++) + for (int i = 0; i < 4; i++) _goblins[i] = 0; - _currentGoblin = 0; - for (i = 0; i < 16; i++) - _soundData[i] = 0; - for (i = 0; i < 3; i++) { + for (int i = 0; i < 3; i++) { _gobPositions[i].x = 0; _gobPositions[i].y = 0; } + _currentGoblin = 0; + _gobDestX = 0; _gobDestY = 0; _pressedMapX = 0; @@ -136,7 +129,7 @@ Goblin::Goblin(GobEngine *vm) : _vm(vm) { _destItemType = 0; _destItemState = 0; - for (i = 0; i < 20; i++) { + for (int i = 0; i < 20; i++) { _itemToObject[i] = 0; _objects[i] = 0; } @@ -144,16 +137,15 @@ Goblin::Goblin(GobEngine *vm) : _vm(vm) { _gobsCount = 0; _soundSlotsCount = 0; - for (i = 0; i < 60; i++) + for (int i = 0; i < 60; i++) _soundSlots[i] = -1; - warning("GOB2 Stub! _word_2F9C0, _word_2F9BE, _word_2F9BC, _word_2F9BA, _dword_2F9B6, _dword_2F9B2"); - _word_2F9C0 = 0; - _word_2F9BE = 0; - _word_2F9BC = 0; - _word_2F9BA = 0; - _dword_2F9B6 = 0; - _dword_2F9B2 = 0; + _gob1Busy = false; + _gob2Busy = false; + _gob1RelaxTimeVar = 0; + _gob2RelaxTimeVar = 0; + _gob1NoTurn = false; + _gob2NoTurn = false; } Goblin::~Goblin() { @@ -164,36 +156,32 @@ Goblin::~Goblin() { for (i = 0; i < 4; i++) { if (_goblins[i]) { - if (_goblins[i]->stateMach) { + if (_goblins[i]->realStateMach) { for (state = 0; state < (i == 3 ? 70 : 40); state++) - if (_goblins[i]->stateMach[state]) + if (_goblins[i]->realStateMach[state]) for (col = 0; col < 6; col++) - if (_goblins[i]->stateMach[state][col]) - delete _goblins[i]->stateMach[state][col]; - delete []_goblins[i]->stateMach; + if (_goblins[i]->realStateMach[state][col]) + delete _goblins[i]->realStateMach[state][col]; + delete []_goblins[i]->realStateMach; } delete _goblins[i]; } } for (i = 0; i < 20; i++) { if (_objects[i]) { - if (_objects[i]->stateMach) { + if (_objects[i]->realStateMach) { for (state = 0; state < 40; state++) for (col = 0; col < 6; col++) - if (_objects[i]->stateMach[state][col]) - delete _objects[i]->stateMach[state][col]; - delete []_objects[i]->stateMach; + if (_objects[i]->realStateMach[state][col]) + delete _objects[i]->realStateMach[state][col]; + delete []_objects[i]->realStateMach; } delete _objects[i]; } } for (i = 0; i < 16; i++) - if (_soundData[i]) { - if (_soundData[i]->data) - delete[] _soundData[i]->data; - delete _soundData[i]; - } + _soundData[i].free(); } char Goblin::rotateState(int16 from, int16 to) { @@ -215,10 +203,10 @@ int16 Goblin::peekGoblin(Gob_Object *_curGob) { if (desc != _goblins[i]) continue; - if (_vm->_global->_inter_mouseX < desc->right && - _vm->_global->_inter_mouseX > desc->left && - _vm->_global->_inter_mouseY < desc->bottom && - _vm->_global->_inter_mouseY > desc->top) { + if ((_vm->_global->_inter_mouseX < desc->right) && + (_vm->_global->_inter_mouseX > desc->left) && + (_vm->_global->_inter_mouseY < desc->bottom) && + (_vm->_global->_inter_mouseY > desc->top)) { index = i + 1; } } @@ -263,8 +251,8 @@ void Goblin::sortByOrder(Util::List *list) { } } -void Goblin::playSound(Snd::SoundDesc *snd, int16 repCount, int16 freq) { - if (snd != 0) { +void Goblin::playSound(SoundDesc &snd, int16 repCount, int16 freq) { + if (!snd.empty()) { _vm->_snd->stopSound(0); _vm->_snd->playSample(snd, repCount, freq); } @@ -293,7 +281,7 @@ void Goblin::drawObjects(void) { if (objDesc->toRedraw == 0) continue; - _vm->_video->drawSprite(_vm->_anim->_animSurf, _vm->_draw->_backSurface, + _vm->_video->drawSprite(_vm->_mult->_animSurf, _vm->_draw->_backSurface, objDesc->left, objDesc->top, objDesc->right, objDesc->bottom, objDesc->left, objDesc->top, 0); @@ -379,9 +367,8 @@ void Goblin::drawObjects(void) { continue; } - if (objDesc->type == 0 && objDesc->visible != 0) { - for (ptr2 = _objList->pHead; ptr2 != 0; - ptr2 = ptr2->pNext) { + if ((objDesc->type == 0) && (objDesc->visible != 0)) { + for (ptr2 = _objList->pHead; ptr2 != 0; ptr2 = ptr2->pNext) { gobDesc2 = (Gob_Object *) ptr2->pData; if (gobDesc2->toRedraw == 0) @@ -419,7 +406,7 @@ void Goblin::drawObjects(void) { for (ptr = _objList->pHead; ptr != 0; ptr = ptr->pNext) { objDesc = (Gob_Object *) ptr->pData; - if (objDesc->toRedraw == 0 || objDesc->type == 1) + if ((objDesc->toRedraw == 0) || (objDesc->type == 1)) continue; Gob_State *state = objDesc->stateMach[objDesc->state][objDesc->stateColumn]; @@ -428,33 +415,31 @@ void Goblin::drawObjects(void) { int16 freq; int16 repCount; - if (state->sndFrame & 0xff00) { + if (state->sndFrame & 0xFF00) { // There are two frames which trigger a sound effect, // so everything has to be encoded in one byte each. // Note that the frequency is multiplied by 100, not - // as I would have thought, 0x100. - sndFrame = (state->sndFrame >> 8) & 0xff; - sndItem = (state->sndItem >> 8) & 0xff; - freq = 100 * ((state->freq >> 8) & 0xff); - repCount = (state->repCount >> 8) & 0xff; + sndFrame = (state->sndFrame >> 8) & 0xFF; + sndItem = (state->sndItem >> 8) & 0xFF; + freq = 100 * ((state->freq >> 8) & 0xFF); + repCount = (state->repCount >> 8) & 0xFF; if (objDesc->curFrame == sndFrame) { - if (sndItem != 0xff) { - playSound(_soundData[sndItem], - repCount, freq); + if (sndItem != 0xFF) { + playSound(_soundData[sndItem], repCount, freq); } } - sndFrame = state->sndFrame & 0xff; - sndItem = state->sndItem & 0xff; - freq = 100 * (state->freq & 0xff); - repCount = state->repCount & 0xff; + sndFrame = state->sndFrame & 0xFF; + sndItem = state->sndItem & 0xFF; + freq = 100 * (state->freq & 0xFF); + repCount = state->repCount & 0xFF; if (objDesc->curFrame == sndFrame) { - if (sndItem != 0xff) { - playSound(_soundData[sndItem], - repCount, freq); + if (sndItem != 0xFF) { + playSound(_soundData[sndItem], repCount, freq); } } } else { @@ -466,14 +451,11 @@ void Goblin::drawObjects(void) { if (objDesc->curFrame == sndFrame) { if (sndItem != -1) { - playSound(_soundData[sndItem], - repCount, freq); + playSound(_soundData[sndItem], repCount, freq); } } } } - -// _vm->_scenery->updateAnim(27, 0, 9, 2, 10, 10, 1); } void Goblin::animateObjects(void) { @@ -484,7 +466,7 @@ void Goblin::animateObjects(void) { for (node = _objList->pHead; node != 0; node = node->pNext) { objDesc = (Gob_Object *) node->pData; - if (objDesc->doAnim != 1 || objDesc->type != 0) + if ((objDesc->doAnim != 1) || (objDesc->type != 0)) continue; if (objDesc->noTick != 0) @@ -498,8 +480,7 @@ void Goblin::animateObjects(void) { objDesc->curFrame++; layer = objDesc->stateMach[objDesc->state][0]->layer; - pLayer = - &_vm->_scenery->_animations[objDesc->animation].layers[layer]; + pLayer = _vm->_scenery->getAnimLayer(objDesc->animation, layer); if (objDesc->curFrame < pLayer->framesCount) continue; @@ -509,9 +490,9 @@ void Goblin::animateObjects(void) { objDesc->xPos += pLayer->animDeltaX; objDesc->yPos += pLayer->animDeltaY; - if (objDesc->nextState == -1 - && objDesc->multState == -1 - && objDesc->unk14 == 0) { + if ((objDesc->nextState == -1) && + (objDesc->multState == -1) && + (objDesc->unk14 == 0)) { objDesc->toRedraw = 0; objDesc->curFrame = pLayer->framesCount - 1; } @@ -548,26 +529,26 @@ int16 Goblin::getObjMaxFrame(Gob_Object * objDesc) { int16 layer; layer = objDesc->stateMach[objDesc->state][0]->layer; - return _vm->_scenery->_animations[objDesc->animation].layers[layer].framesCount - 1; + return _vm->_scenery->getAnimLayer(objDesc->animation, layer)->framesCount - 1; } -int16 Goblin::objIntersected(Gob_Object *obj1, Gob_Object *obj2) { - if (obj1->type == 1 || obj2->type == 1) - return 0; +bool Goblin::objIntersected(Gob_Object *obj1, Gob_Object *obj2) { + if ((obj1->type == 1) || (obj2->type == 1)) + return false; if (obj1->right < obj2->left) - return 0; + return false; if (obj1->left > obj2->right) - return 0; + return false; if (obj1->bottom < obj2->top) - return 0; + return false; if (obj1->top > obj2->bottom) - return 0; + return false; - return 1; + return true; } void Goblin::setMultStates(Gob_Object * gobDesc) { @@ -608,8 +589,7 @@ void Goblin::showBoredom(int16 gobIndex) { gobDesc = _goblins[gobIndex]; layer = gobDesc->stateMach[gobDesc->state][0]->layer; - frameCount = - _vm->_scenery->_animations[gobDesc->animation].layers[layer].framesCount; + frameCount = _vm->_scenery->getAnimLayer(gobDesc->animation, layer)->framesCount; state = gobDesc->state; frame = gobDesc->curFrame; @@ -633,8 +613,8 @@ void Goblin::showBoredom(int16 gobIndex) { } } gobDesc->nextState = 21; - } else if (state >= 18 && state <= 21 && VAR(59) == 0) { - if (state == 30 || state == 31) // ??? + } else if ((state >= 18) && (state <= 21) && (VAR(59) == 0)) { + if ((state == 30) || (state == 31)) // ??? return; if (frame != frameCount) @@ -654,11 +634,11 @@ void Goblin::switchGoblin(int16 index) { if (VAR(59) != 0) return; - if (_goblins[_currentGoblin]->state <= 39 && - _goblins[_currentGoblin]->curFrame != 0) + if ((_goblins[_currentGoblin]->state <= 39) && + (_goblins[_currentGoblin]->curFrame != 0)) return; - if (index != 0 && _goblins[index - 1]->type != 0) + if ((index != 0) && (_goblins[index - 1]->type != 0)) return; if (index == 0) @@ -666,12 +646,12 @@ void Goblin::switchGoblin(int16 index) { else next = index - 1; - if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 3 || - _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6) + if ((_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 3) || + (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6)) return; - if (_goblins[(_currentGoblin + 1) % 3]->type != 0 && - _goblins[(_currentGoblin + 2) % 3]->type != 0) + if ((_goblins[(_currentGoblin + 1) % 3]->type != 0) && + (_goblins[(_currentGoblin + 2) % 3]->type != 0)) return; _gobPositions[_currentGoblin].x = _vm->_map->_curGoblinX; @@ -719,60 +699,52 @@ void Goblin::adjustDest(int16 posX, int16 posY) { int16 deltaPix; int16 i; - if (_vm->_map->getPass(_pressedMapX, _pressedMapY) == 0 && - (_gobAction == 0 - || _vm->_map->_itemsMap[_pressedMapY][_pressedMapX] == 0)) { + if ((_vm->_map->getPass(_pressedMapX, _pressedMapY) == 0) && + ((_gobAction == 0) || + (_vm->_map->_itemsMap[_pressedMapY][_pressedMapX] == 0))) { resDelta = -1; resDeltaDir = 0; resDeltaPix = 0; - for (i = 1; - i <= _pressedMapX - && _vm->_map->getPass(_pressedMapX - i, _pressedMapY) == 0; - i++); + for (i = 1; (i <= _pressedMapX) && + (_vm->_map->getPass(_pressedMapX - i, _pressedMapY) == 0); i++); if (i <= _pressedMapX) { resDeltaPix = (i - 1) * 12 + (posX % 12) + 1; resDelta = i; } - for (i = 1; - (i + _pressedMapX) < _vm->_map->_mapWidth - && _vm->_map->getPass(_pressedMapX + i, _pressedMapY) == 0; - i++); + for (i = 1; ((i + _pressedMapX) < _vm->_map->_mapWidth) && + (_vm->_map->getPass(_pressedMapX + i, _pressedMapY) == 0); i++); - if (_pressedMapX + i < _vm->_map->_mapWidth) { + if ((_pressedMapX + i) < _vm->_map->_mapWidth) { deltaPix = (i * 12) - (posX % 12); - if (resDelta == -1 || deltaPix < resDeltaPix) { + if ((resDelta == -1) || (deltaPix < resDeltaPix)) { resDeltaPix = deltaPix; resDelta = i; resDeltaDir = 1; } } - for (i = 1; - (i + _pressedMapY) < _vm->_map->_mapHeight - && _vm->_map->getPass(_pressedMapX, _pressedMapY + i) == 0; - i++); + for (i = 1; ((i + _pressedMapY) < _vm->_map->_mapHeight) && + (_vm->_map->getPass(_pressedMapX, _pressedMapY + i) == 0); i++); - if (_pressedMapY + i < _vm->_map->_mapHeight) { + if ((_pressedMapY + i) < _vm->_map->_mapHeight) { deltaPix = (i * 6) - (posY % 6); - if (resDelta == -1 || deltaPix < resDeltaPix) { + if ((resDelta == -1) || (deltaPix < resDeltaPix)) { resDeltaPix = deltaPix; resDelta = i; resDeltaDir = 2; } } - for (i = 1; - i <= _pressedMapY - && _vm->_map->getPass(_pressedMapX, _pressedMapY - i) == 0; - i++); + for (i = 1; (i <= _pressedMapY) && + (_vm->_map->getPass(_pressedMapX, _pressedMapY - i) == 0); i++); if (i <= _pressedMapY) { deltaPix = (i * 6) + (posY % 6); - if (resDelta == -1 || deltaPix < resDeltaPix) { + if ((resDelta == -1) || (deltaPix < resDeltaPix)) { resDeltaPix = deltaPix; resDelta = i; resDeltaDir = 3; @@ -803,20 +775,18 @@ void Goblin::adjustDest(int16 posX, int16 posY) { } void Goblin::adjustTarget(void) { - if (_gobAction == 4 - && _vm->_map->_itemsMap[_pressedMapY][_pressedMapX] == 0) { + if ((_gobAction == 4) && + (_vm->_map->_itemsMap[_pressedMapY][_pressedMapX] == 0)) { - if (_pressedMapY > 0 - && _vm->_map->_itemsMap[_pressedMapY - 1][_pressedMapX] != - 0) { + if ((_pressedMapY > 0) && + (_vm->_map->_itemsMap[_pressedMapY - 1][_pressedMapX] != 0)) { _pressedMapY--; - } else if (_pressedMapX < _vm->_map->_mapWidth - 1 - && _vm->_map->_itemsMap[_pressedMapY][_pressedMapX + 1] != - 0) { + } else if ((_pressedMapX < (_vm->_map->_mapWidth - 1)) && + (_vm->_map->_itemsMap[_pressedMapY][_pressedMapX + 1] != 0)) { _pressedMapX++; - } else if (_pressedMapX < _vm->_map->_mapWidth - 1 && _pressedMapY > 0 - && _vm->_map->_itemsMap[_pressedMapY - 1][_pressedMapX + - 1] != 0) { + } else if ((_pressedMapX < (_vm->_map->_mapWidth - 1)) && + (_pressedMapY > 0) && + (_vm->_map->_itemsMap[_pressedMapY - 1][_pressedMapX + 1] != 0)) { _pressedMapY--; _pressedMapX++; } @@ -849,26 +819,25 @@ void Goblin::targetItem(void) { int16 tmpPosY; Gob_Object *itemDesc; - if (_gobAction == 3 || _gobAction == 4) { + if ((_gobAction == 3) || (_gobAction == 4)) { items = _vm->_map->_itemsMap[_pressedMapY][_pressedMapX]; - if (_gobAction == 4 && (items & 0xff00) != 0 && - _objects[_itemToObject[(items & 0xff00) >> 8]]-> - pickable == 1) { - _destItemId = (items & 0xff00) >> 8; - _destActionItem = (items & 0xff00) >> 8; + if ((_gobAction == 4) && ((items & 0xFF00) != 0) && + (_objects[_itemToObject[(items & 0xFF00) >> 8]]->pickable == 1)) { + _destItemId = (items & 0xFF00) >> 8; + _destActionItem = (items & 0xFF00) >> 8; _itemByteFlag = 1; - } else if ((items & 0xff) == 0) { - _destItemId = (items & 0xff00) >> 8; - _destActionItem = (items & 0xff00) >> 8; + } else if ((items & 0xFF) == 0) { + _destItemId = (items & 0xFF00) >> 8; + _destActionItem = (items & 0xFF00) >> 8; _itemByteFlag = 1; - } else if (_gobAction == 3 && _currentGoblin == 2 && - (items & 0xff00) != 0) { - _destItemId = (items & 0xff00) >> 8; - _destActionItem = (items & 0xff00) >> 8; + } else if ((_gobAction == 3) && (_currentGoblin == 2) && + ((items & 0xFF00) != 0)) { + _destItemId = (items & 0xFF00) >> 8; + _destActionItem = (items & 0xFF00) >> 8; _itemByteFlag = 1; } else { - _destItemId = items & 0xff; - _destActionItem = items & 0xff; + _destItemId = items & 0xFF; + _destActionItem = items & 0xFF; _itemByteFlag = 0; } @@ -876,56 +845,46 @@ void Goblin::targetItem(void) { _vm->_map->_destY = _vm->_map->_itemPoses[_destItemId].y; _gobDestY = _vm->_map->_itemPoses[_destItemId].y; - if (_gobAction == 3 || _destActionItem == 0) { + if ((_gobAction == 3) || (_destActionItem == 0)) { _pressedMapX = _vm->_map->_itemPoses[_destItemId].x; _vm->_map->_destX = _vm->_map->_itemPoses[_destItemId].x; _gobDestX = _vm->_map->_itemPoses[_destItemId].x; - } else if ((items & 0xff00) != 0) { + } else if ((items & 0xFF00) != 0) { if (_vm->_map->_itemPoses[_destItemId].orient == 4) { - if ((_vm->_map->_itemsMap[_pressedMapY] - [_pressedMapX - 1] & 0xff00) == - (_vm->_map->_itemsMap[_pressedMapY] - [_pressedMapX] & 0xff00)) { + if ((_vm->_map->_itemsMap[_pressedMapY][_pressedMapX - 1] & 0xFF00) == + (_vm->_map->_itemsMap[_pressedMapY][_pressedMapX] & 0xFF00)) { _pressedMapX--; _vm->_map->_destX = _pressedMapX; _gobDestX = _pressedMapX; } } else if (_vm->_map->_itemPoses[_destItemId].orient == 0) { - if ((_vm->_map->_itemsMap[_pressedMapY] - [_pressedMapX + 1] & 0xff00) == - (_vm->_map->_itemsMap[_pressedMapY] - [_pressedMapX] & 0xff00)) { + if ((_vm->_map->_itemsMap[_pressedMapY][_pressedMapX + 1] & 0xFF00) == + (_vm->_map->_itemsMap[_pressedMapY][_pressedMapX] & 0xFF00)) { _pressedMapX++; _vm->_map->_destX = _pressedMapX; _gobDestX = _pressedMapX; } } - if ((_vm->_map->_itemsMap[_pressedMapY + - 1][_pressedMapX] & 0xff00) == - (_vm->_map->_itemsMap[_pressedMapY][_pressedMapX] & - 0xff00)) { + if ((_vm->_map->_itemsMap[_pressedMapY + 1][_pressedMapX] & 0xFF00) == + (_vm->_map->_itemsMap[_pressedMapY][_pressedMapX] & 0xFF00)) { _pressedMapY++; _vm->_map->_destY = _pressedMapY; _gobDestY = _pressedMapY; } } else { if (_vm->_map->_itemPoses[_destItemId].orient == 4) { - if ((_vm->_map->_itemsMap[_pressedMapY] - [_pressedMapX - 1]) == - (_vm->_map->_itemsMap[_pressedMapY] - [_pressedMapX])) { + if ((_vm->_map->_itemsMap[_pressedMapY][_pressedMapX - 1]) == + (_vm->_map->_itemsMap[_pressedMapY][_pressedMapX])) { _pressedMapX--; _vm->_map->_destX = _pressedMapX; _gobDestX = _pressedMapX; } } else if (_vm->_map->_itemPoses[_destItemId].orient == 0) { - if ((_vm->_map->_itemsMap[_pressedMapY] - [_pressedMapX + 1]) == - (_vm->_map->_itemsMap[_pressedMapY] - [_pressedMapX])) { + if ((_vm->_map->_itemsMap[_pressedMapY][_pressedMapX + 1]) == + (_vm->_map->_itemsMap[_pressedMapY][_pressedMapX])) { _pressedMapX++; _vm->_map->_destX = _pressedMapX; _gobDestX = _pressedMapX; @@ -933,8 +892,7 @@ void Goblin::targetItem(void) { } if (_pressedMapY < (_vm->_map->_mapHeight-1)) { - if ((_vm->_map->_itemsMap[_pressedMapY + - 1][_pressedMapX]) == + if ((_vm->_map->_itemsMap[_pressedMapY + 1][_pressedMapX]) == (_vm->_map->_itemsMap[_pressedMapY][_pressedMapX])) { _pressedMapY++; _vm->_map->_destY = _pressedMapY; @@ -944,19 +902,15 @@ void Goblin::targetItem(void) { } - if (_gobAction == 4 && _destActionItem != 0 && - _itemToObject[_destActionItem] != -1 && - _objects[_itemToObject[_destActionItem]]-> - pickable == 1) { + if ((_gobAction == 4) && (_destActionItem != 0) && + (_itemToObject[_destActionItem] != -1) && + (_objects[_itemToObject[_destActionItem]]->pickable == 1)) { - itemDesc = - _objects[_itemToObject[_destActionItem]]; + itemDesc = _objects[_itemToObject[_destActionItem]]; - itemDesc->animation = - itemDesc->stateMach[itemDesc->state][0]->animation; + itemDesc->animation = itemDesc->stateMach[itemDesc->state][0]->animation; layer = - itemDesc->stateMach[itemDesc->state][itemDesc-> - stateColumn]->layer; + itemDesc->stateMach[itemDesc->state][itemDesc->stateColumn]->layer; _vm->_scenery->updateAnim(layer, 0, itemDesc->animation, 0, itemDesc->xPos, itemDesc->yPos, 0); @@ -965,15 +919,15 @@ void Goblin::targetItem(void) { tmpY = _vm->_scenery->_toRedrawBottom; tmpPosY = tmpY / 6; - if ((tmpY % 3) < 3 && tmpPosY > 0) + if (((tmpY % 3) < 3) && (tmpPosY > 0)) tmpPosY--; tmpPosX = tmpX / 12; - if ((tmpX % 12) < 6 && tmpPosX > 0) + if (((tmpX % 12) < 6) && (tmpPosX > 0)) tmpPosX--; - if (_vm->_map->_itemPoses[_destActionItem].orient == 0 || - _vm->_map->_itemPoses[_destActionItem].orient == -1) { + if ((_vm->_map->_itemPoses[_destActionItem].orient == 0) || + (_vm->_map->_itemPoses[_destActionItem].orient == -1)) { tmpPosX++; } @@ -994,7 +948,7 @@ void Goblin::targetItem(void) { void Goblin::moveFindItem(int16 posX, int16 posY) { int16 i; - if (_gobAction == 3 || _gobAction == 4) { + if ((_gobAction == 3) || (_gobAction == 4)) { for (i = 0; i < 20; i++) { if (_objects[i] == 0) continue; @@ -1014,15 +968,11 @@ void Goblin::moveFindItem(int16 posX, int16 posY) { if (_objects[i]->bottom < posY) continue; - if (_objects[i]->right - _objects[i]->left < 40) - posX = - (_objects[i]->left + - _objects[i]->right) / 2; + if ((_objects[i]->right - _objects[i]->left) < 40) + posX = (_objects[i]->left + _objects[i]->right) / 2; - if (_objects[i]->bottom - _objects[i]->top < 40) - posY = - (_objects[i]->top + - _objects[i]->bottom) / 2; + if ((_objects[i]->bottom - _objects[i]->top) < 40) + posY = (_objects[i]->top + _objects[i]->bottom) / 2; break; } @@ -1030,37 +980,26 @@ void Goblin::moveFindItem(int16 posX, int16 posY) { _pressedMapX = posX / 12; _pressedMapY = posY / 6; - if (_vm->_map->_itemsMap[_pressedMapY][_pressedMapX] == 0 - && i < 20) { + if ((_vm->_map->_itemsMap[_pressedMapY][_pressedMapX] == 0) && (i < 20)) { - if (_vm->_map->_itemsMap[_pressedMapY + - 1][_pressedMapX] != 0) { + if (_vm->_map->_itemsMap[_pressedMapY + 1][_pressedMapX] != 0) { _pressedMapY++; - } else if (_vm->_map->_itemsMap[_pressedMapY + - 1][_pressedMapX + 1] != 0) { + } else if (_vm->_map->_itemsMap[_pressedMapY + 1][_pressedMapX + 1] != 0) { _pressedMapX++; _pressedMapY++; - } else - if (_vm->_map->_itemsMap[_pressedMapY][_pressedMapX + - 1] != 0) { + } else if (_vm->_map->_itemsMap[_pressedMapY][_pressedMapX + 1] != 0) { _pressedMapX++; - } else if (_vm->_map->_itemsMap[_pressedMapY - - 1][_pressedMapX + 1] != 0) { + } else if (_vm->_map->_itemsMap[_pressedMapY - 1][_pressedMapX + 1] != 0) { _pressedMapX++; _pressedMapY--; - } else if (_vm->_map->_itemsMap[_pressedMapY - - 1][_pressedMapX] != 0) { + } else if (_vm->_map->_itemsMap[_pressedMapY - 1][_pressedMapX] != 0) { _pressedMapY--; - } else if (_vm->_map->_itemsMap[_pressedMapY - - 1][_pressedMapX - 1] != 0) { + } else if (_vm->_map->_itemsMap[_pressedMapY - 1][_pressedMapX - 1] != 0) { _pressedMapY--; _pressedMapX--; - } else - if (_vm->_map->_itemsMap[_pressedMapY][_pressedMapX - - 1] != 0) { + } else if (_vm->_map->_itemsMap[_pressedMapY][_pressedMapX - 1] != 0) { _pressedMapX--; - } else if (_vm->_map->_itemsMap[_pressedMapY + - 1][_pressedMapX - 1] != 0) { + } else if (_vm->_map->_itemsMap[_pressedMapY + 1][_pressedMapX - 1] != 0) { _pressedMapX--; _pressedMapY++; } @@ -1073,12 +1012,13 @@ void Goblin::moveFindItem(int16 posX, int16 posY) { _pressedMapY = CLIP((int) _pressedMapY, 0, _vm->_map->_mapHeight - 1); } -void Goblin::moveCheckSelect(int16 framesCount, Gob_Object * gobDesc, int16 *pGobIndex, - int16 *nextAct) { - if (gobDesc->right > _vm->_global->_inter_mouseX && - gobDesc->left < _vm->_global->_inter_mouseX && - gobDesc->bottom > _vm->_global->_inter_mouseY && - gobDesc->bottom - 10 < _vm->_global->_inter_mouseY && _gobAction == 0) { +void Goblin::moveCheckSelect(int16 framesCount, Gob_Object *gobDesc, + int16 *pGobIndex, int16 *nextAct) { + if ((gobDesc->right > _vm->_global->_inter_mouseX) && + (gobDesc->left < _vm->_global->_inter_mouseX) && + (gobDesc->bottom > _vm->_global->_inter_mouseY) && + ((gobDesc->bottom - 10) < _vm->_global->_inter_mouseY) && + (_gobAction == 0)) { if (gobDesc->curLookDir & 4) *nextAct = 16; else @@ -1091,8 +1031,8 @@ void Goblin::moveCheckSelect(int16 framesCount, Gob_Object * gobDesc, int16 *pGo if (*pGobIndex != 0) { _pathExistence = 0; - } else if (_vm->_map->_curGoblinX == _pressedMapX && - _vm->_map->_curGoblinY == _pressedMapY) { + } else if ((_vm->_map->_curGoblinX == _pressedMapX) && + (_vm->_map->_curGoblinY == _pressedMapY)) { if (_gobAction != 0) _readyToAct = 1; @@ -1107,10 +1047,10 @@ void Goblin::moveInitStep(int16 framesCount, int16 action, int16 cont, int16 posX; int16 posY; - if (cont != 0 && _goesAtTarget == 0 && - _readyToAct == 0 && VAR(59) == 0 && - gobDesc->type != 1 && - gobDesc->state != 10 && gobDesc->state != 11) { + if ((cont != 0) && (_goesAtTarget == 0) && + (_readyToAct == 0) && (VAR(59) == 0) && + (gobDesc->type != 1) && + (gobDesc->state != 10) && (gobDesc->state != 11)) { if (gobDesc->state >= 40) { gobDesc->curFrame = framesCount - 1; } @@ -1149,9 +1089,8 @@ void Goblin::moveInitStep(int16 framesCount, int16 action, int16 cont, moveCheckSelect(framesCount, gobDesc, pGobIndex, pNextAct); } else { - if (_readyToAct != 0 && - (_vm->_map->_curGoblinX != _pressedMapX || - _vm->_map->_curGoblinY != _pressedMapY)) + if ((_readyToAct != 0) && ((_vm->_map->_curGoblinX != _pressedMapX) || + (_vm->_map->_curGoblinY != _pressedMapY))) _readyToAct = 0; if (gobDesc->type == 1) { @@ -1164,58 +1103,56 @@ void Goblin::moveTreatRopeStairs(Gob_Object *gobDesc) { if (_currentGoblin != 1) return; - if (gobDesc->nextState == 28 - && _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY - 1) == 6) { + if ((gobDesc->nextState == 28) && + (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY - 1) == 6)) { _forceNextState[0] = 28; _forceNextState[1] = -1; } - if (gobDesc->nextState == 29 - && _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY + 1) == 6) { + if ((gobDesc->nextState == 29) && + (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY + 1) == 6)) { _forceNextState[0] = 29; _forceNextState[1] = -1; } - if ((gobDesc->nextState == 28 || gobDesc->nextState == 29 - || gobDesc->nextState == 20) - && _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6) { - if ((gobDesc->curLookDir == 0 || gobDesc->curLookDir == 4 - || gobDesc->curLookDir == 2) - && _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY - 1) == 6) { + if (((gobDesc->nextState == 28) || (gobDesc->nextState == 29) || + (gobDesc->nextState == 20)) && + (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6)) { + if (((gobDesc->curLookDir == 0) || (gobDesc->curLookDir == 4) || + (gobDesc->curLookDir == 2)) && + (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY - 1) == 6)) { _forceNextState[0] = 28; _forceNextState[1] = -1; - } else if ((gobDesc->curLookDir == 0 - || gobDesc->curLookDir == 4 - || gobDesc->curLookDir == 6) - && _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY + 1) == 6) { + } else if (((gobDesc->curLookDir == 0) || (gobDesc->curLookDir == 4) || + (gobDesc->curLookDir == 6)) && + (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY + 1) == 6)) { _forceNextState[0] = 29; _forceNextState[1] = -1; } } - if (gobDesc->nextState == 8 - && _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY - 1) == 3) { + if ((gobDesc->nextState == 8) && + (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY - 1) == 3)) { _forceNextState[0] = 8; _forceNextState[1] = -1; } - if (gobDesc->nextState == 9 - && _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY + 1) == 3) { + if ((gobDesc->nextState == 9) && + (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY + 1) == 3)) { _forceNextState[0] = 9; _forceNextState[1] = -1; } - if (gobDesc->nextState == 20 - && _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 3) { - if ((gobDesc->curLookDir == 0 || gobDesc->curLookDir == 4 - || gobDesc->curLookDir == 2) - && _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY - 1) == 3) { + if ((gobDesc->nextState == 20) && + (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 3)) { + if (((gobDesc->curLookDir == 0) || (gobDesc->curLookDir == 4) || + (gobDesc->curLookDir == 2)) && + (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY - 1) == 3)) { _forceNextState[0] = 8; _forceNextState[1] = -1; - } else if ((gobDesc->curLookDir == 0 - || gobDesc->curLookDir == 4 - || gobDesc->curLookDir == 6) - && _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY + 1) == 3) { + } else if (((gobDesc->curLookDir == 0) || (gobDesc->curLookDir == 4) || + (gobDesc->curLookDir == 6)) + && (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY + 1) == 3)) { _forceNextState[0] = 9; _forceNextState[1] = -1; } @@ -1233,11 +1170,10 @@ int16 Goblin::doMove(Gob_Object *gobDesc, int16 cont, int16 action) { gobIndex = 0; layer = gobDesc->stateMach[gobDesc->state][0]->layer; - framesCount = - _vm->_scenery->_animations[gobDesc->animation].layers[layer].framesCount; + framesCount = _vm->_scenery->getAnimLayer(gobDesc->animation, layer)->framesCount; - if (VAR(59) == 0 && - gobDesc->state != 30 && gobDesc->state != 31) { + if ((VAR(59) == 0) && + (gobDesc->state != 30) && (gobDesc->state != 31)) { gobDesc->order = (gobDesc->bottom) / 24 + 3; } @@ -1249,14 +1185,12 @@ int16 Goblin::doMove(Gob_Object *gobDesc, int16 cont, int16 action) { _positionedGob = _currentGoblin; gobDesc->animation = - gobDesc->stateMach[gobDesc->state][gobDesc->stateColumn]-> - animation; + gobDesc->stateMach[gobDesc->state][gobDesc->stateColumn]->animation; _gobStateLayer = gobDesc->stateMach[gobDesc->state][gobDesc->stateColumn]->layer; - moveInitStep(framesCount, action, cont, gobDesc, &gobIndex, - &nextAct); + moveInitStep(framesCount, action, cont, gobDesc, &gobIndex, &nextAct); moveTreatRopeStairs(gobDesc); moveAdvance(0, gobDesc, nextAct, framesCount); @@ -1264,16 +1198,14 @@ int16 Goblin::doMove(Gob_Object *gobDesc, int16 cont, int16 action) { } void Goblin::zeroObjects(void) { - int16 i; - - for (i = 0; i < 4; i++) + for (int i = 0; i < 4; i++) _goblins[i] = 0; - for (i = 0; i < 20; i++) + for (int i = 0; i < 20; i++) _objects[i] = 0; - for (i = 0; i < 16; i++) - _soundData[i] = 0; + for (int i = 0; i < 16; i++) + _vm->_snd->freeSample(_soundData[i]); } void Goblin::freeAllObjects(void) { @@ -1283,10 +1215,8 @@ void Goblin::freeAllObjects(void) { } void Goblin::loadObjects(char *source) { - int16 i; - zeroObjects(); - for (i = 0; i < 20; i++) + for (int i = 0; i < 20; i++) _itemToObject[i] = 100; freeObjects(); @@ -1296,12 +1226,11 @@ void Goblin::loadObjects(char *source) { _vm->_map->_sourceFile[strlen(_vm->_map->_sourceFile) - 4] = 0; _vm->_map->loadMapObjects(source); - for (i = 0; i < _gobsCount; i++) + for (int i = 0; i < _gobsCount; i++) placeObject(_goblins[i], 0, 0, 0, 0, 0); - for (i = 0; i < _objCount; i++) { + for (int i = 0; i < _objCount; i++) placeObject(_objects[i], 1, 0, 0, 0, 0); - } initVarPointers(); _actDestItemDesc = 0; @@ -1479,14 +1408,11 @@ void Goblin::loadGobDataFromVars(void) { if (obj->type != _destItemType) obj->toRedraw = 1; - if (obj->state != _destItemState && obj->type == 0) + if ((obj->state != _destItemState) && (obj->type == 0)) obj->toRedraw = 1; } void Goblin::pickItem(int16 indexToPocket, int16 idToPocket) { - int16 x; - int16 y; - if (_objects[indexToPocket]->pickable != 1) return; @@ -1495,20 +1421,19 @@ void Goblin::pickItem(int16 indexToPocket, int16 idToPocket) { _itemIndInPocket = indexToPocket; _itemIdInPocket = idToPocket; - for (y = 0; y < _vm->_map->_mapHeight; y++) { - for (x = 0; x < _vm->_map->_mapWidth; x++) { + for (int y = 0; y < _vm->_map->_mapHeight; y++) { + for (int x = 0; x < _vm->_map->_mapWidth; x++) { if (_itemByteFlag == 1) { - if (((_vm->_map->_itemsMap[y][x] & 0xff00) >> 8) == - idToPocket) - _vm->_map->_itemsMap[y][x] &= 0xff; + if (((_vm->_map->_itemsMap[y][x] & 0xFF00) >> 8) == idToPocket) + _vm->_map->_itemsMap[y][x] &= 0xFF; } else { - if ((_vm->_map->_itemsMap[y][x] & 0xff) == idToPocket) - _vm->_map->_itemsMap[y][x] &= 0xff00; + if ((_vm->_map->_itemsMap[y][x] & 0xFF) == idToPocket) + _vm->_map->_itemsMap[y][x] &= 0xFF00; } } } - if (idToPocket >= 0 && idToPocket < 20) { + if ((idToPocket >= 0) && (idToPocket < 20)) { _vm->_map->_itemPoses[_itemIdInPocket].x = 0; _vm->_map->_itemPoses[_itemIdInPocket].y = 0; _vm->_map->_itemPoses[_itemIdInPocket].orient = 0; @@ -1544,51 +1469,48 @@ void Goblin::placeItem(int16 indexInPocket, int16 idInPocket) { _vm->_scenery->updateAnim(layer, 0, itemDesc->animation, 0, itemDesc->xPos, itemDesc->yPos, 0); - itemDesc->yPos += - (_gobPositions[0].y * 6) + 5 - _vm->_scenery->_toRedrawBottom; + itemDesc->yPos += (_gobPositions[0].y * 6) + 5 - + _vm->_scenery->_toRedrawBottom; - if (lookDir == 4) { - itemDesc->xPos += (_gobPositions[0].x * 12 + 14) - - (_vm->_scenery->_toRedrawLeft + _vm->_scenery->_toRedrawRight) / 2; - } else { - itemDesc->xPos += (_gobPositions[0].x * 12) - - (_vm->_scenery->_toRedrawLeft + _vm->_scenery->_toRedrawRight) / 2; - } + if (lookDir == 4) + itemDesc->xPos += (_gobPositions[0].x * 12 + 14) - + (_vm->_scenery->_toRedrawLeft + _vm->_scenery->_toRedrawRight) / 2; + else + itemDesc->xPos += (_gobPositions[0].x * 12) - + (_vm->_scenery->_toRedrawLeft + _vm->_scenery->_toRedrawRight) / 2; _vm->_map->placeItem(xPos, yPos, idInPocket); - if (yPos > 0) { + if (yPos > 0) _vm->_map->placeItem(xPos, yPos - 1, idInPocket); - } if (lookDir == 4) { if (xPos < _vm->_map->_mapWidth - 1) { _vm->_map->placeItem(xPos + 1, yPos, idInPocket); - if (yPos > 0) { + if (yPos > 0) _vm->_map->placeItem(xPos + 1, yPos - 1, idInPocket); - } } } else { if (xPos > 0) { _vm->_map->placeItem(xPos - 1, yPos, idInPocket); - if (yPos > 0) { + if (yPos > 0) _vm->_map->placeItem(xPos - 1, yPos - 1, idInPocket); - } } } - if (idInPocket >= 0 && idInPocket < 20) { + if ((idInPocket >= 0) && (idInPocket < 20)) { _vm->_map->_itemPoses[idInPocket].x = _gobPositions[0].x; _vm->_map->_itemPoses[idInPocket].y = _gobPositions[0].y; _vm->_map->_itemPoses[idInPocket].orient = lookDir; if (_vm->_map->_itemPoses[idInPocket].orient == 0) { -// _vm->_map->_itemPoses[idInPocket].x++; - if (_vm->_map->getPass(_vm->_map->_itemPoses[idInPocket].x + 1, (int)_vm->_map->_itemPoses[idInPocket].y) == 1) + if (_vm->_map->getPass(_vm->_map->_itemPoses[idInPocket].x + 1, + (int)_vm->_map->_itemPoses[idInPocket].y) == 1) _vm->_map->_itemPoses[idInPocket].x++; } else { - if (_vm->_map->getPass(_vm->_map->_itemPoses[idInPocket].x - 1, (int)_vm->_map->_itemPoses[idInPocket].y) == 1) + if (_vm->_map->getPass(_vm->_map->_itemPoses[idInPocket].x - 1, + (int)_vm->_map->_itemPoses[idInPocket].y) == 1) _vm->_map->_itemPoses[idInPocket].x--; } } @@ -1599,8 +1521,7 @@ void Goblin::swapItems(int16 indexToPick, int16 idToPick) { Gob_Object *pickObj; Gob_Object *placeObj; int16 idToPlace; - int16 x; - int16 y; + int16 x, y; pickObj = _objects[indexToPick]; placeObj = _objects[_itemIndInPocket]; @@ -1613,21 +1534,18 @@ void Goblin::swapItems(int16 indexToPick, int16 idToPick) { if (_itemByteFlag == 0) { for (y = 0; y < _vm->_map->_mapHeight; y++) { for (x = 0; x < _vm->_map->_mapWidth; x++) { - if ((_vm->_map->_itemsMap[y][x] & 0xff) == idToPick) + if ((_vm->_map->_itemsMap[y][x] & 0xFF) == idToPick) _vm->_map->_itemsMap[y][x] = - (_vm->_map->_itemsMap[y][x] & 0xff00) + - idToPlace; + (_vm->_map->_itemsMap[y][x] & 0xFF00) + idToPlace; } } } else { for (y = 0; y < _vm->_map->_mapHeight; y++) { for (x = 0; x < _vm->_map->_mapWidth; x++) { - if (((_vm->_map->_itemsMap[y][x] & 0xff00) >> 8) == - idToPick) + if (((_vm->_map->_itemsMap[y][x] & 0xFF00) >> 8) == idToPick) _vm->_map->_itemsMap[y][x] = - (_vm->_map->_itemsMap[y][x] & 0xff) + - (idToPlace << 8); + (_vm->_map->_itemsMap[y][x] & 0xFF) + (idToPlace << 8); } } } @@ -1659,21 +1577,19 @@ void Goblin::swapItems(int16 indexToPick, int16 idToPick) { placeObj->animation = placeObj->stateMach[placeObj->state][0]->animation; - layer = - placeObj->stateMach[placeObj->state][placeObj->stateColumn]->layer; + layer = placeObj->stateMach[placeObj->state][placeObj->stateColumn]->layer; _vm->_scenery->updateAnim(layer, 0, placeObj->animation, 0, placeObj->xPos, placeObj->yPos, 0); - placeObj->yPos += - (_gobPositions[0].y * 6) + 5 - _vm->_scenery->_toRedrawBottom; + placeObj->yPos += (_gobPositions[0].y * 6) + 5 - + _vm->_scenery->_toRedrawBottom; - if (_vm->_map->_itemPoses[idToPlace].orient == 4) { - placeObj->xPos += (_gobPositions[0].x * 12 + 14) - - (_vm->_scenery->_toRedrawLeft + _vm->_scenery->_toRedrawRight) / 2; - } else { - placeObj->xPos += (_gobPositions[0].x * 12) - - (_vm->_scenery->_toRedrawLeft + _vm->_scenery->_toRedrawRight) / 2; - } + if (_vm->_map->_itemPoses[idToPlace].orient == 4) + placeObj->xPos += (_gobPositions[0].x * 12 + 14) - + (_vm->_scenery->_toRedrawLeft + _vm->_scenery->_toRedrawRight) / 2; + else + placeObj->xPos += (_gobPositions[0].x * 12) - + (_vm->_scenery->_toRedrawLeft + _vm->_scenery->_toRedrawRight) / 2; } void Goblin::treatItemPick(int16 itemId) { @@ -1692,27 +1608,26 @@ void Goblin::treatItemPick(int16 itemId) { _goesAtTarget = 0; itemIndex = _itemToObject[itemId]; - if (itemId != 0 && itemIndex != -1 - && _objects[itemIndex]->pickable != 1) + if ((itemId != 0) && (itemIndex != -1) && (_objects[itemIndex]->pickable != 1)) itemIndex = -1; - if (_itemIndInPocket != -1 && _itemIndInPocket == itemIndex) + if ((_itemIndInPocket != -1) && (_itemIndInPocket == itemIndex)) itemIndex = -1; - if (_itemIndInPocket != -1 && itemIndex != -1 - && _objects[itemIndex]->pickable == 1) { + if ((_itemIndInPocket != -1) && (itemIndex != -1) && + (_objects[itemIndex]->pickable == 1)) { swapItems(itemIndex, itemId); _itemIndInPocket = itemIndex; _itemIdInPocket = itemId; return; } - if (_itemIndInPocket != -1 && itemIndex == -1) { + if ((_itemIndInPocket != -1) && (itemIndex == -1)) { placeItem(_itemIndInPocket, _itemIdInPocket); return; } - if (_itemIndInPocket == -1 && itemIndex != -1) { + if ((_itemIndInPocket == -1) && (itemIndex != -1)) { pickItem(itemIndex, itemId); return; } @@ -1722,21 +1637,21 @@ int16 Goblin::treatItem(int16 action) { int16 state; state = _goblins[_currentGoblin]->state; - if ((state == 10 || state == 11) && - _goblins[_currentGoblin]->curFrame == 0) { + if (((state == 10) || (state == 11)) && + (_goblins[_currentGoblin]->curFrame == 0)) { _readyToAct = 0; } - if (action == 3 && _currentGoblin == 0 && - (state == 10 || state == 11) && _goblins[0]->curFrame == 0) { + if ((action == 3) && (_currentGoblin == 0) && + ((state == 10) || (state == 11)) && (_goblins[0]->curFrame == 0)) { saveGobDataToVars(_gobPositions[_currentGoblin].x, _gobPositions[_currentGoblin].y, 0); _goesAtTarget = 1; return -1; } - if (_noPick == 0 && _currentGoblin == 0 && - (state == 10 || state == 11)) { + if ((_noPick == 0) && (_currentGoblin == 0) && + ((state == 10) || (state == 11))) { treatItemPick(_destActionItem); saveGobDataToVars(_gobPositions[_currentGoblin].x, @@ -1750,16 +1665,11 @@ int16 Goblin::treatItem(int16 action) { return 0; } else { - if (_itemToObject[_destActionItem] != 100 && - _destActionItem != 0) { - - if (_itemToObject[_destActionItem] == -1) { + if ((_itemToObject[_destActionItem] != 100) && (_destActionItem != 0)) { + if (_itemToObject[_destActionItem] == -1) _actDestItemDesc = 0; - } else { - _actDestItemDesc = - _objects[_itemToObject - [_destActionItem]]; - } + else + _actDestItemDesc = _objects[_itemToObject[_destActionItem]]; } _goesAtTarget = 0; @@ -1770,7 +1680,6 @@ int16 Goblin::treatItem(int16 action) { } void Goblin::playSounds(Mult::Mult_Object *obj) { - int i; Mult::Mult_AnimData *animData; bool speaker; int16 frequency; @@ -1780,28 +1689,33 @@ void Goblin::playSounds(Mult::Mult_Object *obj) { animData = obj->pAnimData; - for (i = 1; i <= obj->goblinStates[animData->state][0].dataCount; i++) { + for (int i = 1; i <= obj->goblinStates[animData->state][0].dataCount; i++) { speaker = obj->goblinStates[animData->state][i].speaker != 0; - if ((obj->goblinStates[animData->state][i].sndItem != -1) || (speaker == 1)) { + + if ((obj->goblinStates[animData->state][i].sndItem != -1) || + (speaker == 1)) { + frame = obj->goblinStates[animData->state][i].sndFrame; repCount = obj->goblinStates[animData->state][i].repCount; frequency = obj->goblinStates[animData->state][i].freq; - if (animData->frame == frame) { - if (!speaker) { - sndSlot = obj->goblinStates[animData->state][i].sndItem; - _vm->_snd->stopSound(0); - if (sndSlot < _soundSlotsCount) - _vm->_snd->playSample(_vm->_game->_soundSamples[_soundSlots[sndSlot] & 0x7FFF], - repCount, frequency); - } else - _vm->_snd->speakerOn(frequency, repCount * 10); - } + if (animData->frame != frame) + continue; + + if (!speaker) { + sndSlot = obj->goblinStates[animData->state][i].sndItem; + _vm->_snd->stopSound(0); + if (sndSlot < _soundSlotsCount) + _vm->_snd->playSample(_vm->_game->_soundSamples[_soundSlots[sndSlot] & 0x7FFF], + repCount, frequency); + } else + _vm->_snd->speakerOn(frequency, repCount * 10); + } } } -void Goblin::sub_195C7(int16 index, int16 state) { +void Goblin::setState(int16 index, int16 state) { Mult::Mult_Object *obj; Mult::Mult_AnimData *animData; int16 layer; @@ -1821,7 +1735,7 @@ void Goblin::sub_195C7(int16 index, int16 state) { animData->frame = 0; animData->isPaused = 0; animData->isStatic = 0; - animData->newCycle = _vm->_scenery->_animations[animation].layers[layer].framesCount; + animData->newCycle = _vm->_scenery->getAnimLayer(animation, layer)->framesCount; _vm->_scenery->updateAnim(layer, 0, animation, 0, *obj->pPosX, *obj->pPosY, 1); if (_vm->_map->_bigTiles) { @@ -1835,7 +1749,7 @@ void Goblin::sub_195C7(int16 index, int16 state) { *obj->pPosX = obj->goblinX * _vm->_map->_tilesWidth; } -void Goblin::sub_11984(Mult::Mult_Object *obj) { +void Goblin::animate(Mult::Mult_Object *obj) { Mult::Mult_AnimData *animData; int16 layer; int16 animation; @@ -1848,14 +1762,14 @@ void Goblin::sub_11984(Mult::Mult_Object *obj) { layer = obj->goblinStates[animData->state][0].layer; animation = obj->goblinStates[animData->state][0].animation; - framesCount = _vm->_scenery->_animations[animation].layers[layer].framesCount; + framesCount = _vm->_scenery->getAnimLayer(animation, layer)->framesCount; animData->newCycle = framesCount; playSounds(obj); if (animData->isPaused == 0) animData->frame++; - switch (animData->field_16) { + switch (animData->stateType) { case 0: case 1: animData->isPaused = 0; @@ -1872,143 +1786,73 @@ void Goblin::sub_11984(Mult::Mult_Object *obj) { break; } - if ((animData->field_F == -1) && (animData->frame >= framesCount)) { - if (animData->field_15 <= 0) { - animData->field_15 = animData->unknown; + if ((animData->newState == -1) && (animData->frame >= framesCount)) { + if (animData->framesLeft <= 0) { + animData->framesLeft = animData->maxFrame; animData->frame = 0; } else - animData->field_15--; + animData->framesLeft --; } if (animData->frame < framesCount) return; - if (animData->field_F != -1) { + if (animData->newState != -1) { animData->frame = 0; - animData->state = animData->field_F; - animData->field_F = -1; + animData->state = animData->newState; + animData->newState = -1; animData->animation = obj->goblinStates[animData->state][0].animation; animData->layer = obj->goblinStates[animData->state][0].layer; - *obj->pPosX += _vm->_scenery->_animations[animation].layers[layer].animDeltaX; - *obj->pPosY += _vm->_scenery->_animations[animation].layers[layer].animDeltaY; - animData->newCycle = _vm->_scenery->_animations[animation].layers[layer].framesCount; + + Scenery::AnimLayer *animLayer = _vm->_scenery->getAnimLayer(animation, layer); + *obj->pPosX += animLayer->animDeltaX; + *obj->pPosY += animLayer->animDeltaY; + animData->newCycle = animLayer->framesCount; animData->isPaused = 0; } else animData->frame--; } -void Goblin::sub_197A6(int16 destX, int16 destY, int16 objIndex) { +void Goblin::move(int16 destX, int16 destY, int16 objIndex) { Mult::Mult_Object *obj; Mult::Mult_AnimData *animData; int16 mouseX; int16 mouseY; int16 gobDestX; int16 gobDestY; - int16 mapWidth; - int16 mapHeight; - int16 di; - int16 si; - int16 var_1E; - int16 var_20; - int i; obj = &_vm->_mult->_objects[objIndex]; animData = obj->pAnimData; obj->gobDestX = destX; obj->gobDestY = destY; - animData->field_13 = destX; - animData->field_14 = destY; + animData->destX = destX; + animData->destY = destY; - if ((animData->isBusy != 0) && (destX != -1) && (destY != -1)) { + if (animData->isBusy != 0) { if ((destX == -1) && (destY == -1)) { mouseX = _vm->_global->_inter_mouseX; mouseY = _vm->_global->_inter_mouseY; if (_vm->_map->_bigTiles) mouseY += ((_vm->_global->_inter_mouseY / _vm->_map->_tilesHeight) + 1) / 2; - obj->gobDestX = mouseX / _vm->_map->_tilesWidth; - obj->gobDestY = mouseY / _vm->_map->_tilesHeight; - gobDestX = obj->gobDestX; - gobDestY = obj->gobDestY; - if (_vm->_map->getPass(obj->gobDestX, obj->gobDestY) == 0) { - mapWidth = _vm->_map->_screenWidth / _vm->_map->_tilesWidth; - mapHeight = 200 / _vm->_map->_tilesHeight; - var_20 = 0; - di = -1; - si = -1; - - for (i = 1; i <= gobDestX; i++) - if (_vm->_map->getPass(gobDestX - i, gobDestY) != 0) - break; - if (i <= gobDestX) - di = ((i - 1) * _vm->_map->_tilesWidth) + (mouseX % _vm->_map->_tilesWidth) + 1; - var_1E = i; - - for (i = 1; (gobDestX + i) < mapWidth; i++) - if (_vm->_map->getPass(gobDestX + i, gobDestY) != 0) - break; - if ((gobDestX + i) < mapWidth) - si = (i * _vm->_map->_tilesWidth) - (mouseX % _vm->_map->_tilesWidth); - - if ((si != -1) && ((di == -1) || (di > si))) { - di = si; - var_20 = 1; - var_1E = i; - } - si = -1; - - for (i = 1; (gobDestY + i) < mapHeight; i++) - if (_vm->_map->getPass(gobDestX, gobDestY + i) != 0) - break; - if ((gobDestY + i) < mapHeight) - si = (i * _vm->_map->_tilesHeight) - (mouseY % _vm->_map->_tilesHeight); - - if ((si != -1) && ((di == -1) || (di > si))) { - di = si; - var_20 = 2; - var_1E = i; - } - si = -1; + + gobDestX = mouseX / _vm->_map->_tilesWidth; + gobDestY = mouseY / _vm->_map->_tilesHeight; - for (i = 1; i <= gobDestY; i++) - if (_vm->_map->getPass(gobDestX, gobDestY - i) != 0) - break; - if (i <= gobDestY) - si = ((i - 1) * _vm->_map->_tilesHeight) + (mouseY % _vm->_map->_tilesHeight) + 1; - - if ((si != -1) && ((di == -1) || (di > si))) { - var_20 = 3; - var_1E = i; - } + if (_vm->_map->getPass(gobDestX, gobDestY) == 0) + _vm->_map->findNearestWalkable(gobDestX, gobDestY, mouseX, mouseY); - if (var_20 == 0) - gobDestX -= var_1E; - else if (var_20 == 1) - gobDestX += var_1E; - else if (var_20 == 2) - gobDestY += var_1E; - else if (var_20 == 3) - gobDestY -= var_1E; - } - obj->gobDestX = gobDestX; - obj->gobDestY = gobDestY; - animData->field_13 = gobDestX; - animData->field_14 = gobDestY; - if (animData->field_13 == -1) { - animData->field_13 = obj->goblinX; - obj->gobDestX = obj->goblinX; - } - if (animData->field_14 == -1) { - animData->field_14 = obj->goblinY; - obj->gobDestY = obj->goblinY; - } + animData->destX = obj->gobDestX = + (gobDestX == -1) ? obj->goblinX : gobDestX; + animData->destY = obj->gobDestY = + (gobDestY == -1) ? obj->goblinY : gobDestY; } } initiateMove(obj); } -void Goblin::sub_19AB7(Mult::Mult_AnimData *animData) { - switch(animData->state) { +void Goblin::updateLayer1(Mult::Mult_AnimData *animData) { + switch (animData->state) { case 2: animData->layer = 8; break; @@ -2039,8 +1883,8 @@ void Goblin::sub_19AB7(Mult::Mult_AnimData *animData) { } } -void Goblin::sub_19B45(Mult::Mult_AnimData *animData) { - switch(animData->state) { +void Goblin::updateLayer2(Mult::Mult_AnimData *animData) { + switch (animData->state) { case 2: animData->layer = 10; break; diff --git a/engines/gob/goblin.h b/engines/gob/goblin.h index 517b0a908f..d00de048f2 100644 --- a/engines/gob/goblin.h +++ b/engines/gob/goblin.h @@ -20,10 +20,10 @@ * $Id$ * */ + #ifndef GOB_GOBLIN_H #define GOB_GOBLIN_H -#include "gob/gob.h" #include "gob/util.h" #include "gob/sound.h" #include "gob/mult.h" @@ -41,14 +41,14 @@ public: #include "common/pack-start.h" // START STRUCT PACKING struct Gob_State { - int16 animation;// +0h - int16 layer; // +2h - int16 unk0; // +4h - int16 unk1; // +6h - int16 sndItem; // +8h, high/low byte - sound sample index - int16 freq; // +Ah, high/low byte * 100 - frequency - int16 repCount; // +Ch high/low byte - repeat count - int16 sndFrame; // +Eh + int16 animation; + int16 layer; + int16 unk0; + int16 unk1; + int16 sndItem; // high/low byte - sound sample index + int16 freq; // high/low byte * 100 - frequency + int16 repCount; // high/low byte - repeat count + int16 sndFrame; }; typedef Gob_State *Gob_PState; @@ -56,38 +56,38 @@ public: typedef Gob_PState Gob_StateLine[6]; struct Gob_Object { - int16 animation; // +0h - int16 state; // +2h - int16 stateColumn; // +4h - int16 curFrame; // +6h - int16 xPos; // +8h - int16 yPos; // +Ah - int16 dirtyLeft; // +Ch - int16 dirtyTop; // +Eh - int16 dirtyRight; // +10h - int16 dirtyBottom; // +12h - int16 left; // +14h - int16 top; // +16h - int16 right; // +18h - int16 bottom; // +1ah - int16 nextState; // +1ch - int16 multState; // +1eh - int16 actionStartState; // +20h - int16 curLookDir; // +22h - int16 pickable; // +24h - int16 relaxTime; // +26h - Gob_StateLine *stateMach; // +28h - Gob_StateLine *realStateMach; // +2ch - char doAnim; // +30h - int8 order; // +31h - char noTick; // +32h - char toRedraw; // +33h - char type; // +34h - char maxTick; // +35h - char tick; // +36h - char multObjIndex; // +37h, from which play mult animations - char unk14; // +38h - char visible; // +39h + int16 animation; + int16 state; + int16 stateColumn; + int16 curFrame; + int16 xPos; + int16 yPos; + int16 dirtyLeft; + int16 dirtyTop; + int16 dirtyRight; + int16 dirtyBottom; + int16 left; + int16 top; + int16 right; + int16 bottom; + int16 nextState; + int16 multState; + int16 actionStartState; + int16 curLookDir; + int16 pickable; + int16 relaxTime; + Gob_StateLine *stateMach; + Gob_StateLine *realStateMach; + char doAnim; + int8 order; + char noTick; + char toRedraw; + char type; + char maxTick; + char tick; + char multObjIndex; + char unk14; + char visible; }; struct Gob_Pos { @@ -97,15 +97,14 @@ public: #include "common/pack-end.h" // END STRUCT PACKING - Util::List *_objList; Gob_Object *_goblins[4]; int16 _currentGoblin; - Snd::SoundDesc *_soundData[16]; + SoundDesc _soundData[16]; int16 _gobStateLayer; char _goesAtTarget; char _readyToAct; int16 _gobAction; // 0 - move, 3 - do action, 4 - pick - // goblins 0 - picker, 1 - fighter, 2 - mage + // goblins: 0 - picker, 1 - fighter, 2 - mage Gob_Pos _gobPositions[3]; int16 _gobDestX; int16 _gobDestY; @@ -183,23 +182,23 @@ public: int16 _positionedGob; char _noPick; - // GOB2: + // Gob2: int16 _soundSlotsCount; int16 _soundSlots[60]; - int16 _word_2F9C0; - int16 _word_2F9BE; - int16 _word_2F9BC; - int16 _word_2F9BA; - int16 _dword_2F9B6; // index into the variables array - int16 _dword_2F9B2; // index into the variables array + bool _gob1Busy; + bool _gob2Busy; + int16 _gob1RelaxTimeVar; + int16 _gob2RelaxTimeVar; + bool _gob1NoTurn; + bool _gob2NoTurn; // Functions char rotateState(int16 from, int16 to); - void playSound(Snd::SoundDesc * snd, int16 repCount, int16 freq); + void playSound(SoundDesc &snd, int16 repCount, int16 freq); void drawObjects(void); void animateObjects(void); int16 getObjMaxFrame(Gob_Object * obj); - int16 objIntersected(Gob_Object * obj1, Gob_Object * obj2); + bool objIntersected(Gob_Object * obj1, Gob_Object * obj2); void setMultStates(Gob_Object * gobDesc); int16 nextLayer(Gob_Object * gobDesc); void showBoredom(int16 gobIndex); @@ -217,11 +216,11 @@ public: int16 treatItem(int16 action); int16 doMove(Gob_Object *gobDesc, int16 cont, int16 action); - void sub_195C7(int16 index, int16 state); - void sub_11984(Mult::Mult_Object *obj); - void sub_197A6(int16 destX, int16 destY, int16 objIndex); - void sub_19AB7(Mult::Mult_AnimData *animData); - void sub_19B45(Mult::Mult_AnimData *animData); + void setState(int16 index, int16 state); + void updateLayer1(Mult::Mult_AnimData *animData); + void updateLayer2(Mult::Mult_AnimData *animData); + void move(int16 destX, int16 destY, int16 objIndex); + void animate(Mult::Mult_Object *obj); virtual void handleGoblins(void) = 0; virtual void placeObject(Gob_Object * objDesc, char animated, @@ -235,7 +234,9 @@ public: virtual ~Goblin(); protected: + Util::List *_objList; int16 _rotStates[4][4]; + GobEngine *_vm; int16 peekGoblin(Gob_Object *curGob); @@ -246,13 +247,15 @@ protected: void targetDummyItem(Gob_Object *gobDesc); void targetItem(void); void moveFindItem(int16 posX, int16 posY); - void moveCheckSelect(int16 framesCount, Gob_Object * gobDesc, int16 *pGobIndex, int16 *nextAct); + void moveCheckSelect(int16 framesCount, Gob_Object * gobDesc, + int16 *pGobIndex, int16 *nextAct); void moveInitStep(int16 framesCount, int16 action, int16 cont, Gob_Object *gobDesc, int16 *pGobIndex, int16 *pNextAct); void moveTreatRopeStairs(Gob_Object *gobDesc); void playSounds(Mult::Mult_Object *obj); - virtual void movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 nextAct) = 0; + virtual void movePathFind(Mult::Mult_Object *obj, + Gob_Object *gobDesc, int16 nextAct) = 0; }; class Goblin_v1 : public Goblin { @@ -269,7 +272,8 @@ public: virtual ~Goblin_v1() {}; protected: - virtual void movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 nextAct); + virtual void movePathFind(Mult::Mult_Object *obj, + Gob_Object *gobDesc, int16 nextAct); }; class Goblin_v2 : public Goblin_v1 { @@ -286,9 +290,10 @@ public: virtual ~Goblin_v2() {}; protected: - virtual void movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 nextAct); + virtual void movePathFind(Mult::Mult_Object *obj, + Gob_Object *gobDesc, int16 nextAct); }; -} // End of namespace Gob +} // End of namespace Gob -#endif /* __GOBLIN_H */ +#endif // GOB_GOBLIN_H diff --git a/engines/gob/goblin_v1.cpp b/engines/gob/goblin_v1.cpp index 4c46906a60..4c39cb399f 100644 --- a/engines/gob/goblin_v1.cpp +++ b/engines/gob/goblin_v1.cpp @@ -26,8 +26,11 @@ #include "gob/gob.h" #include "gob/goblin.h" -#include "gob/scenery.h" +#include "gob/util.h" #include "gob/map.h" +#include "gob/mult.h" +#include "gob/scenery.h" +#include "gob/sound.h" namespace Gob { @@ -39,19 +42,13 @@ Goblin_v1::Goblin_v1(GobEngine *vm) : Goblin(vm) { } void Goblin_v1::freeObjects(void) { - int16 i; int16 state; int16 col; - for (i = 0; i < 16; i++) { - if (_soundData[i] == 0) - continue; - - _vm->_snd->freeSoundDesc(_soundData[i]); - _soundData[i] = 0; - } + for (int i = 0; i < 16; i++) + _vm->_snd->freeSample(_soundData[i]); - for (i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { if (_goblins[i] == 0) continue; @@ -76,7 +73,7 @@ void Goblin_v1::freeObjects(void) { _goblins[i] = 0; } - for (i = 0; i < 20; i++) { + for (int i = 0; i < 20; i++) { if (_objects[i] == 0) continue; @@ -100,8 +97,7 @@ void Goblin_v1::placeObject(Gob_Object *objDesc, char animated, int16 layer; if (objDesc->stateMach[objDesc->state][0] != 0) { - objDesc->animation = - objDesc->stateMach[objDesc->state][0]->animation; + objDesc->animation = objDesc->stateMach[objDesc->state][0]->animation; objDesc->noTick = 0; objDesc->toRedraw = 1; @@ -147,7 +143,8 @@ void Goblin_v1::initiateMove(Mult::Mult_Object *obj) { _vm->_map->findNearestToGob(0); _vm->_map->optimizePoints(0, 0, 0); - _pathExistence = _vm->_map->checkDirectPath(0, _vm->_map->_curGoblinX, _vm->_map->_curGoblinY, + _pathExistence = _vm->_map->checkDirectPath(0, + _vm->_map->_curGoblinX, _vm->_map->_curGoblinY, _pressedMapX, _pressedMapY); if (_pathExistence == 3) { @@ -162,19 +159,21 @@ void Goblin_v1::initiateMove(Mult::Mult_Object *obj) { } } -void Goblin_v1::movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 nextAct) { +void Goblin_v1::movePathFind(Mult::Mult_Object *obj, + Gob_Object *gobDesc, int16 nextAct) { + if (_pathExistence == 1) { _vm->_map->_curGoblinX = _gobPositions[_currentGoblin].x; _vm->_map->_curGoblinY = _gobPositions[_currentGoblin].y; - if (_vm->_map->_curGoblinX == _pressedMapX && - _vm->_map->_curGoblinY == _pressedMapY && _gobAction != 0) { + if ((_vm->_map->_curGoblinX == _pressedMapX) && + (_vm->_map->_curGoblinY == _pressedMapY) && (_gobAction != 0)) { _readyToAct = 1; _pathExistence = 0; } - nextAct = _vm->_map->getDirection(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY, - _vm->_map->_destX, _vm->_map->_destY); + nextAct = _vm->_map->getDirection(_vm->_map->_curGoblinX, + _vm->_map->_curGoblinY, _vm->_map->_destX, _vm->_map->_destY); if (nextAct == 0) _pathExistence = 0; @@ -182,27 +181,27 @@ void Goblin_v1::movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 _vm->_map->_curGoblinX = _gobPositions[_currentGoblin].x; _vm->_map->_curGoblinY = _gobPositions[_currentGoblin].y; - if (_vm->_map->_curGoblinX == _gobDestX && _vm->_map->_curGoblinY == _gobDestY) { + if ((_vm->_map->_curGoblinX == _gobDestX) && + (_vm->_map->_curGoblinY == _gobDestY)) { _pathExistence = 1; _vm->_map->_destX = _pressedMapX; _vm->_map->_destY = _pressedMapY; } else { - if (_vm->_map->checkDirectPath(0, _vm->_map->_curGoblinX, _vm->_map->_curGoblinY, - _gobDestX, _gobDestY) == 1) { + if (_vm->_map->checkDirectPath(0, _vm->_map->_curGoblinX, + _vm->_map->_curGoblinY, _gobDestX, _gobDestY) == 1) { _vm->_map->_destX = _gobDestX; _vm->_map->_destY = _gobDestY; - } else if (_vm->_map->_curGoblinX == _vm->_map->_destX && _vm->_map->_curGoblinY == _vm->_map->_destY) { + } else if ((_vm->_map->_curGoblinX == _vm->_map->_destX) && + (_vm->_map->_curGoblinY == _vm->_map->_destY)) { if (_vm->_map->_nearestWayPoint > _vm->_map->_nearestDest) { _vm->_map->optimizePoints(0, 0, 0); _vm->_map->_destX = - _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint]. - x; + _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].x; _vm->_map->_destY = - _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint]. - y; + _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].y; if (_vm->_map->_nearestWayPoint > _vm->_map->_nearestDest) _vm->_map->_nearestWayPoint--; @@ -210,18 +209,16 @@ void Goblin_v1::movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 _vm->_map->optimizePoints(0, 0, 0); _vm->_map->_destX = - _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint]. - x; + _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].x; _vm->_map->_destY = - _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint]. - y; + _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].y; if (_vm->_map->_nearestWayPoint < _vm->_map->_nearestDest) _vm->_map->_nearestWayPoint++; } else { - if (_vm->_map->checkDirectPath(0, _vm->_map->_curGoblinX, - _vm->_map->_curGoblinY, _gobDestX, - _gobDestY) == 3 && _vm->_map->getPass(_pressedMapX, _pressedMapY) != 0) { + if ((_vm->_map->checkDirectPath(0, _vm->_map->_curGoblinX, + _vm->_map->_curGoblinY, _gobDestX, _gobDestY) == 3) && + (_vm->_map->getPass(_pressedMapX, _pressedMapY) != 0)) { _vm->_map->_destX = _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].x; _vm->_map->_destY = _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].y; } else { @@ -231,14 +228,13 @@ void Goblin_v1::movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 } } } - nextAct = - _vm->_map->getDirection(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY, - _vm->_map->_destX, _vm->_map->_destY); + nextAct = _vm->_map->getDirection(_vm->_map->_curGoblinX, + _vm->_map->_curGoblinY, _vm->_map->_destX, _vm->_map->_destY); } } - if (_readyToAct != 0 && (_gobAction == 3 || _gobAction == 4)) - nextAct = 0x4dc8; + if ((_readyToAct != 0) && ((_gobAction == 3) || (_gobAction == 4))) + nextAct = 0x4DC8; switch (nextAct) { case Map::kDirW: @@ -258,8 +254,8 @@ void Goblin_v1::movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 break; case Map::kDirN: - if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY - 1) == 6 && - _currentGoblin != 1) { + if ((_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY - 1) == 6) && + (_currentGoblin != 1)) { _pathExistence = 0; break; } @@ -269,8 +265,8 @@ void Goblin_v1::movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 break; } - if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6 && - _currentGoblin == 1) { + if ((_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6) && + (_currentGoblin == 1)) { gobDesc->nextState = 28; break; } @@ -279,8 +275,8 @@ void Goblin_v1::movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 break; case Map::kDirS: - if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY + 1) == 6 && - _currentGoblin != 1) { + if ((_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY + 1) == 6) && + (_currentGoblin != 1)) { _pathExistence = 0; break; } @@ -290,8 +286,8 @@ void Goblin_v1::movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 break; } - if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6 && - _currentGoblin == 1) { + if ((_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6) && + (_currentGoblin == 1)) { gobDesc->nextState = 29; break; } @@ -300,8 +296,8 @@ void Goblin_v1::movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 break; case Map::kDirSE: - if (_vm->_map->getPass(_vm->_map->_curGoblinX + 1, _vm->_map->_curGoblinY + 1) == 6 && - _currentGoblin != 1) { + if ((_vm->_map->getPass(_vm->_map->_curGoblinX + 1, _vm->_map->_curGoblinY + 1) == 6) && + (_currentGoblin != 1)) { _pathExistence = 0; break; } @@ -314,8 +310,8 @@ void Goblin_v1::movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 break; case Map::kDirSW: - if (_vm->_map->getPass(_vm->_map->_curGoblinX - 1, _vm->_map->_curGoblinY + 1) == 6 && - _currentGoblin != 1) { + if ((_vm->_map->getPass(_vm->_map->_curGoblinX - 1, _vm->_map->_curGoblinY + 1) == 6) && + (_currentGoblin != 1)) { _pathExistence = 0; break; } @@ -328,8 +324,8 @@ void Goblin_v1::movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 break; case Map::kDirNW: - if (_vm->_map->getPass(_vm->_map->_curGoblinX - 1, _vm->_map->_curGoblinY - 1) == 6 && - _currentGoblin != 1) { + if ((_vm->_map->getPass(_vm->_map->_curGoblinX - 1, _vm->_map->_curGoblinY - 1) == 6) && + (_currentGoblin != 1)) { _pathExistence = 0; break; } @@ -342,8 +338,8 @@ void Goblin_v1::movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 break; case Map::kDirNE: - if (_vm->_map->getPass(_vm->_map->_curGoblinX + 1, _vm->_map->_curGoblinY - 1) == 6 && - _currentGoblin != 1) { + if ((_vm->_map->getPass(_vm->_map->_curGoblinX + 1, _vm->_map->_curGoblinY - 1) == 6) && + (_currentGoblin != 1)) { _pathExistence = 0; break; } @@ -355,28 +351,27 @@ void Goblin_v1::movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 gobDesc->nextState = rotateState(gobDesc->curLookDir, 4); break; - case 0x4dc8: + case 0x4DC8: - if (_currentGoblin == 0 && _gobAction == 3 - && _itemIndInPocket == -1) { + if ((_currentGoblin == 0) && (_gobAction == 3) && + (_itemIndInPocket == -1)) { _destItemId = -1; _readyToAct = 0; break; } - if (_currentGoblin == 0 && _gobAction == 4 && - _itemIndInPocket == -1 && _destActionItem == 0) { + if ((_currentGoblin == 0) && (_gobAction == 4) && + (_itemIndInPocket == -1) && (_destActionItem == 0)) { gobDesc->multState = 104; _destItemId = -1; _readyToAct = 0; break; } - if (_currentGoblin == 0 && _gobAction == 4 && - _itemIndInPocket == -1 && _destActionItem != 0 && - _itemToObject[_destActionItem] != -1 && - _objects[_itemToObject[_destActionItem]]-> - pickable == 0) { + if ((_currentGoblin == 0) && (_gobAction == 4) && + (_itemIndInPocket == -1 && _destActionItem != 0) && + (_itemToObject[_destActionItem] != -1) && + (_objects[_itemToObject[_destActionItem]]->pickable == 0)) { gobDesc->multState = 104; _destItemId = -1; _readyToAct = 0; @@ -401,9 +396,9 @@ void Goblin_v1::movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 break; default: - if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 3 || - (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6 - && _currentGoblin == 1)) { + if ((_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 3) || + ((_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6) + && (_currentGoblin == 1))) { gobDesc->nextState = 20; break; } @@ -437,8 +432,7 @@ void Goblin_v1::moveAdvance(Mult::Mult_Object *obj, Gob_Object *gobDesc, if (gobDesc->curFrame == 1) gobDesc->actionStartState = gobDesc->state; - if (_goesAtTarget == 0 - && gobDesc->stateMach == gobDesc->realStateMach) { + if ((_goesAtTarget == 0) && (gobDesc->stateMach == gobDesc->realStateMach)) { switch (gobDesc->state) { case 0: case 1: @@ -489,24 +483,22 @@ void Goblin_v1::moveAdvance(Mult::Mult_Object *obj, Gob_Object *gobDesc, } } - if (gobDesc->state >= 0 && gobDesc->state < 10 && - gobDesc->stateMach == gobDesc->realStateMach && - (gobDesc->curFrame == 3 || gobDesc->curFrame == 6)) { + if ((gobDesc->state >= 0) && (gobDesc->state < 10) && + (gobDesc->stateMach == gobDesc->realStateMach) && + ((gobDesc->curFrame == 3) || (gobDesc->curFrame == 6))) { _vm->_snd->speakerOn(10 * _vm->_util->getRandom(3) + 50, 5); } - if (_currentGoblin == 0 - && gobDesc->stateMach == gobDesc->realStateMach - && (gobDesc->state == 10 || gobDesc->state == 11) - && gobDesc->curFrame == 9) { + if ((_currentGoblin == 0) && + (gobDesc->stateMach == gobDesc->realStateMach) && + ((gobDesc->state == 10) || (gobDesc->state == 11)) && + (gobDesc->curFrame == 9)) { _vm->_snd->stopSound(0); - if (_itemIndInPocket != -1) { - _vm->_snd->playSample(_soundData[14], 1, 9000); - } - if (_itemIndInPocket == -1) { + if (_itemIndInPocket != -1) + _vm->_snd->playSample(_soundData[14], 1, 9000); + else _vm->_snd->playSample(_soundData[14], 1, 5000); - } } if (_boreCounter++ == 120) { @@ -515,36 +507,32 @@ void Goblin_v1::moveAdvance(Mult::Mult_Object *obj, Gob_Object *gobDesc, showBoredom(i); } - if (gobDesc->multState != -1 && gobDesc->curFrame == framesCount && - gobDesc->state != gobDesc->multState) { + if ((gobDesc->multState != -1) && (gobDesc->curFrame == framesCount) && + (gobDesc->state != gobDesc->multState)) { gobDesc->nextState = gobDesc->multState; gobDesc->multState = -1; - newX = - _vm->_scenery->_animations[gobDesc->animation]. - layers[_gobStateLayer].animDeltaX + gobDesc->xPos; + newX = _vm->_scenery->getAnimLayer(gobDesc->animation, + _gobStateLayer)->animDeltaX + gobDesc->xPos; - newY = - _vm->_scenery->_animations[gobDesc->animation]. - layers[_gobStateLayer].animDeltaY + gobDesc->yPos; + newY = _vm->_scenery->getAnimLayer(gobDesc->animation, + _gobStateLayer)->animDeltaY + gobDesc->yPos; _gobStateLayer = nextLayer(gobDesc); gobDesc->xPos = newX; gobDesc->yPos = newY; } else { - if (gobDesc->curFrame == 3 && - gobDesc->stateMach == gobDesc->realStateMach && - (gobDesc->state < 10 || - (_currentGoblin == 1 && (gobDesc->state == 28 - || gobDesc->state == 29)) - )) { + if ((gobDesc->curFrame == 3) && + (gobDesc->stateMach == gobDesc->realStateMach) && + ((gobDesc->state < 10) || + ((_currentGoblin == 1) && ((gobDesc->state == 28) || + (gobDesc->state == 29))))) { flag = 0; if (_forceNextState[0] != -1) { gobDesc->nextState = _forceNextState[0]; for (i = 0; i < 9; i++) - _forceNextState[i] = - _forceNextState[i + 1]; + _forceNextState[i] = _forceNextState[i + 1]; } _vm->_map->_curGoblinX = _gobPositions[_currentGoblin].x; @@ -609,8 +597,7 @@ void Goblin_v1::moveAdvance(Mult::Mult_Object *obj, Gob_Object *gobDesc, if (flag != 0) { _vm->_scenery->updateAnim(_gobStateLayer, 0, - gobDesc->animation, 0, gobDesc->xPos, - gobDesc->yPos, 0); + gobDesc->animation, 0, gobDesc->xPos, gobDesc->yPos, 0); gobDesc->yPos = (_vm->_map->_curGoblinY + 1) * 6 - @@ -620,8 +607,8 @@ void Goblin_v1::moveAdvance(Mult::Mult_Object *obj, Gob_Object *gobDesc, _vm->_scenery->_animLeft); } - if ((gobDesc->state == 10 || gobDesc->state == 11) - && _currentGoblin != 0) + if (((gobDesc->state == 10) || (gobDesc->state == 11)) && + (_currentGoblin != 0)) _goesAtTarget = 1; } @@ -631,8 +618,7 @@ void Goblin_v1::moveAdvance(Mult::Mult_Object *obj, Gob_Object *gobDesc, if (_forceNextState[0] != -1) { gobDesc->nextState = _forceNextState[0]; for (i = 0; i < 10; i++) - _forceNextState[i] = - _forceNextState[i + 1]; + _forceNextState[i] = _forceNextState[i + 1]; } _vm->_map->_curGoblinX = _gobPositions[_currentGoblin].x; @@ -700,10 +686,11 @@ void Goblin_v1::moveAdvance(Mult::Mult_Object *obj, Gob_Object *gobDesc, (_vm->_map->_curGoblinY + 1) * 6 - (_vm->_scenery->_toRedrawBottom - _vm->_scenery->_animTop); gobDesc->xPos = - _vm->_map->_curGoblinX * 12 - (_vm->_scenery->_toRedrawLeft - _vm->_scenery->_animLeft); + _vm->_map->_curGoblinX * 12 - + (_vm->_scenery->_toRedrawLeft - _vm->_scenery->_animLeft); - if ((gobDesc->state == 10 || gobDesc->state == 11) - && _currentGoblin != 0) + if (((gobDesc->state == 10) || (gobDesc->state == 11)) && + (_currentGoblin != 0)) _goesAtTarget = 1; } return; diff --git a/engines/gob/goblin_v2.cpp b/engines/gob/goblin_v2.cpp index 4df678f118..ada54fbb5b 100644 --- a/engines/gob/goblin_v2.cpp +++ b/engines/gob/goblin_v2.cpp @@ -26,10 +26,12 @@ #include "gob/gob.h" #include "gob/goblin.h" -#include "gob/mult.h" +#include "gob/global.h" +#include "gob/util.h" #include "gob/game.h" -#include "gob/scenery.h" #include "gob/map.h" +#include "gob/mult.h" +#include "gob/scenery.h" namespace Gob { @@ -42,19 +44,16 @@ Goblin_v2::Goblin_v2(GobEngine *vm) : Goblin_v1(vm) { } void Goblin_v2::freeObjects(void) { - int i; - if (_gobsCount < 0) return; - for (i = 0; i < _gobsCount; i++) { + for (int i = 0; i < _gobsCount; i++) { delete[] _vm->_mult->_objects[i].goblinStates[0]; delete[] _vm->_mult->_objects[i].goblinStates; } - for (i = 0; i < _vm->_goblin->_soundSlotsCount; i++) - if ((_vm->_goblin->_soundSlots[i] & 0x8000) == 0) - _vm->_game->freeSoundSlot(_vm->_goblin->_soundSlots[i]); -// delete[] off_2F2AB; + for (int i = 0; i < _soundSlotsCount; i++) + if ((_soundSlots[i] & 0x8000) == 0) + _vm->_game->freeSoundSlot(_soundSlots[i]); _gobsCount = -1; } @@ -96,7 +95,7 @@ void Goblin_v2::placeObject(Gob_Object *objDesc, char animated, objAnim->frame = 0; objAnim->isPaused = 0; objAnim->isStatic = 0; - objAnim->newCycle = _vm->_scenery->_animations[animation].layers[layer].framesCount; + objAnim->newCycle = _vm->_scenery->getAnimLayer(animation, layer)->framesCount; _vm->_scenery->updateAnim(layer, 0, animation, 0, *obj->pPosX, *obj->pPosY, 0); if (!_vm->_map->_bigTiles) *obj->pPosY = (y + 1) * _vm->_map->_tilesHeight @@ -138,16 +137,15 @@ void Goblin_v2::movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 dir = 0; animData = obj->pAnimData; - framesCount = - _vm->_scenery->_animations[(int)animData->animation].layers[animData->layer].framesCount; + framesCount = _vm->_scenery->getAnimLayer(animData->animation, animData->layer)->framesCount; animData->newCycle = framesCount; gobX = obj->goblinX; gobY = obj->goblinY; animData->order = gobY; gobDestX = obj->gobDestX; gobDestY = obj->gobDestY; - animData->field_13 = gobDestX; - animData->field_14 = gobDestY; + animData->destX = gobDestX; + animData->destY = gobDestY; destX = obj->destX; destY = obj->destY; @@ -175,7 +173,7 @@ void Goblin_v2::movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 } if (obj->nearestWayPoint > obj->nearestDest) obj->nearestWayPoint--; - } else if (obj->nearestWayPoint < obj->nearestDest) { // loc_10E96 + } else if (obj->nearestWayPoint < obj->nearestDest) { _vm->_map->optimizePoints(obj, gobX, gobY); destX = _vm->_map->_wayPoints[obj->nearestWayPoint].x; destY = _vm->_map->_wayPoints[obj->nearestWayPoint].y; @@ -225,7 +223,8 @@ void Goblin_v2::movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 break; case Map::kDirN: - animData->nextState = animData->curLookDir == 2 ? 2 : rotateState(animData->curLookDir, 2); + animData->nextState = + (animData->curLookDir == 2) ? 2 : rotateState(animData->curLookDir, 2); if (_vm->_map->_screenWidth == 640) { if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 10) { if (_vm->_map->getPass(obj->goblinX - 1, obj->goblinY - 2) != 10) { @@ -271,7 +270,8 @@ void Goblin_v2::movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 break; case Map::kDirS: - animData->nextState = animData->curLookDir == 6 ? 6 : rotateState(animData->curLookDir, 6); + animData->nextState = + (animData->curLookDir == 6) ? 6 : rotateState(animData->curLookDir, 6); if (_vm->_map->_screenWidth == 640) { if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 20) animData->nextState = 39; @@ -317,13 +317,12 @@ void Goblin_v2::moveAdvance(Mult::Mult_Object *obj, Gob_Object *gobDesc, animData = obj->pAnimData; - framesCount = - _vm->_scenery->_animations[(int)animData->animation].layers[animData->layer].framesCount; + framesCount = _vm->_scenery->getAnimLayer(animData->animation, animData->layer)->framesCount; if (animData->isPaused == 0) animData->frame++; - switch (animData->field_16) { + switch (animData->stateType) { case 0: case 1: animData->isPaused = 0; @@ -347,7 +346,6 @@ void Goblin_v2::moveAdvance(Mult::Mult_Object *obj, Gob_Object *gobDesc, case 13: case 16: case 23: - // loc_11452 animData->curLookDir = 0; break; @@ -383,15 +381,17 @@ void Goblin_v2::moveAdvance(Mult::Mult_Object *obj, Gob_Object *gobDesc, break; } - if ((animData->field_F != -1) && (animData->frame == framesCount) && - (animData->field_F != animData->state)) { // loc_114B6 - animData->nextState = animData->field_F; - animData->field_F = -1; + if ((animData->newState != -1) && (animData->frame == framesCount) && + (animData->newState != animData->state)) { + animData->nextState = animData->newState; + animData->newState = -1; animData->state = animData->nextState; - *obj->pPosX += - _vm->_scenery->_animations[animData->animation].layers[animData->layer].animDeltaX; - *obj->pPosY += - _vm->_scenery->_animations[animData->animation].layers[animData->layer].animDeltaY; + + Scenery::AnimLayer *animLayer = + _vm->_scenery->getAnimLayer(animData->animation, animData->layer); + *obj->pPosX += animLayer->animDeltaX; + *obj->pPosY += animLayer->animDeltaY; + animation = obj->goblinStates[animData->nextState][0].animation; layer = obj->goblinStates[animData->nextState][0].layer; animData->layer = layer; @@ -399,7 +399,7 @@ void Goblin_v2::moveAdvance(Mult::Mult_Object *obj, Gob_Object *gobDesc, animData->frame = 0; } else { if (((animData->state >= 0) && (animData->state < 8)) || - (animData->state == 38) || (animData->state == 39)) { // loc_115C4 + (animData->state == 38) || (animData->state == 39)) { state = animData->nextState; if (animData->frame == ((framesCount + 1) / 2)) { gobX = obj->goblinX; @@ -524,50 +524,47 @@ void Goblin_v2::moveAdvance(Mult::Mult_Object *obj, Gob_Object *gobDesc, } void Goblin_v2::handleGoblins(void) { - Mult::Mult_Object *obj0; - Mult::Mult_Object *obj1; - Mult::Mult_AnimData *anim0; - Mult::Mult_AnimData *anim1; + Mult::Mult_Object *obj0, *obj1; + Mult::Mult_AnimData *anim0, *anim1; int16 pass; - int16 gob1X; - int16 gob2X; - int16 gob1Y; - int16 gob2Y; - int16 var_A; - int16 var_C; - int16 di; - int16 si; + int16 gob1State, gob2State; + int16 gob1X, gob2X; + int16 gob1Y, gob2Y; + int16 gob1DestX, gob2DestX; + int16 gob1DestY, gob2DestY; obj0 = &_vm->_mult->_objects[0]; obj1 = &_vm->_mult->_objects[1]; anim0 = obj0->pAnimData; anim1 = obj1->pAnimData; - si = anim0->state; - di = anim1->state; + gob1State = anim0->state; + gob2State = anim1->state; - if (anim0->isBusy == 0) { - if ((_word_2F9BC == 0) && (anim0->isStatic == 0)) { - if ((VAR(_dword_2F9B6) == 0) && (si == 28)) { - si = _vm->_util->getRandom(3) + 24; - sub_195C7(0, si); - WRITE_VAR(_dword_2F9B6, 100); + if (!anim0->isBusy) { + if (!_gob1Busy && (anim0->isStatic == 0)) { + if ((VAR(_gob1RelaxTimeVar) == 0) && (gob1State == 28)) { + // Goblin 1 showing boredom + gob1State = _vm->_util->getRandom(3) + 24; + setState(0, gob1State); + WRITE_VAR(_gob1RelaxTimeVar, 100); } else - WRITE_VAR(_dword_2F9B6, VAR(_dword_2F9B6) - 1); + WRITE_VAR(_gob1RelaxTimeVar, VAR(_gob1RelaxTimeVar) - 1); } - if ((si == 8) || (si == 9) || (si == 29)) + if ((gob1State == 8) || (gob1State == 9) || (gob1State == 29)) anim0->curLookDir = 6; } - if (anim1->isBusy == 0) { - if ((_word_2F9BA == 0) && (anim1->isStatic == 0)) { - if ((VAR(_dword_2F9B2) == 0) && (di == 28)) { - di = _vm->_util->getRandom(3) + 24; - sub_195C7(1, di); - WRITE_VAR(_dword_2F9B2, 100); + if (!anim1->isBusy) { + if (!_gob2Busy && (anim1->isStatic == 0)) { + if ((VAR(_gob2RelaxTimeVar) == 0) && (gob2State == 28)) { + // Goblin 2 showing boredom + gob2State = _vm->_util->getRandom(3) + 24; + setState(1, gob2State); + WRITE_VAR(_gob2RelaxTimeVar, 100); } else - WRITE_VAR(_dword_2F9B2, VAR(_dword_2F9B2) - 1); + WRITE_VAR(_gob2RelaxTimeVar, VAR(_gob2RelaxTimeVar) - 1); } - if ((di == 8) || (di == 9) || (di == 29)) + if ((gob2State == 8) || (gob2State == 9) || (gob2State == 29)) anim1->curLookDir = 6; } @@ -596,93 +593,93 @@ void Goblin_v2::handleGoblins(void) { } if ((anim0->layer == 45) && (anim0->curLookDir == 4) && (anim0->pathExistence == 5) && - (VAR(18) == ((uint32) -1)) && (_word_2F9C0 == 0)) { - sub_195C7(0, 19); + (VAR(18) == ((uint32) -1)) && !_gob1NoTurn) { + setState(0, 19); // Turning right->left } if ((anim0->layer == 44) && (anim0->curLookDir == 0) && (anim0->pathExistence == 5) && - (VAR(18) == ((uint32) -1)) && (_word_2F9C0 == 0)) { - sub_195C7(0, 16); + (VAR(18) == ((uint32) -1)) && !_gob1NoTurn) { + setState(0, 16); // Turning left->right } if ((anim1->layer == 49) && (anim1->curLookDir == 4) && (anim1->pathExistence == 5) && - (VAR(19) == ((uint32) -1)) && (_word_2F9BE == 0)) { - sub_195C7(1, 19); + (VAR(19) == ((uint32) -1)) && !_gob2NoTurn) { + setState(1, 19); // Turning right->left } if ((anim1->layer == 48) && (anim1->curLookDir == 0) && (anim1->pathExistence == 5) && - (VAR(19) == ((uint32) -1)) && (_word_2F9BE == 0)) { - sub_195C7(1, 16); + (VAR(19) == ((uint32) -1)) && !_gob2NoTurn) { + setState(1, 16); // Turning left->right } gob1X = obj0->goblinX; gob2X = obj1->goblinX; gob1Y = obj0->goblinY; gob2Y = obj1->goblinY; - di = anim0->field_13; - si = anim0->field_14; - var_A = anim1->field_13; - var_C = anim1->field_14; + gob1DestX = anim0->destX; + gob2DestX = anim1->destX; + gob1DestY = anim0->destY; + gob2DestY = anim1->destY; pass = _vm->_map->getPass(gob1X, gob1Y); - if ((pass > 17) && (pass < 21)) - sub_19AB7(anim0); + if ((pass > 17) && (pass < 21)) // Ladders, ropes, stairs + updateLayer1(anim0); pass = _vm->_map->getPass(gob2X, gob2Y); - if ((pass > 17) && (pass < 21)) - sub_19B45(anim1); + if ((pass > 17) && (pass < 21)) // Ladders, ropes, stairs + updateLayer2(anim1); - if ((di < 0) || (di > 39) || (si < 0) || (si > 39)) + if ((gob1DestX < 0) || (gob1DestX > 39) || (gob1DestY < 0) || (gob1DestY > 39)) return; - if (gob1Y > si) { - if (_vm->_map->getPass(di, si) > 17) { + if (gob1Y > gob1DestY) { + if (_vm->_map->getPass(gob1DestX, gob1DestY) > 17) { do { - si--; - } while (_vm->_map->getPass(di, si) > 17); - si++; - if (_vm->_map->getPass(di - 1, si) == 0) { - if (_vm->_map->getPass(di + 1, si) != 0) - di++; + gob1DestY--; + } while (_vm->_map->getPass(gob1DestX, gob1DestY) > 17); + gob1DestY++; + if (_vm->_map->getPass(gob1DestX - 1, gob1DestY) == 0) { + if (_vm->_map->getPass(gob1DestX + 1, gob1DestY) != 0) + gob1DestX++; } else - di--; - sub_197A6(di, si, 0); + gob1DestX--; + move(gob1DestX, gob1DestY, 0); } } else { - if (_vm->_map->getPass(di, si) > 17) { + if (_vm->_map->getPass(gob1DestX, gob1DestY) > 17) { do { - si++; - } while (_vm->_map->getPass(di, si) > 17); - si--; - if (_vm->_map->getPass(di - 1, si) == 0) { - if (_vm->_map->getPass(di + 1, si) != 0) - di++; + gob1DestY++; + } while (_vm->_map->getPass(gob1DestX, gob1DestY) > 17); + gob1DestY--; + if (_vm->_map->getPass(gob1DestX - 1, gob1DestY) == 0) { + if (_vm->_map->getPass(gob1DestX + 1, gob1DestY) != 0) + gob1DestX++; } else - di--; - sub_197A6(di, si, 0); + gob1DestX--; + move(gob1DestX, gob1DestY, 0); } } - if (gob2Y > var_C) { - if (_vm->_map->getPass(var_A, var_C) > 17) { + if (gob2Y > gob2DestY) { + if (_vm->_map->getPass(gob2DestX, gob2DestY) > 17) { do { - var_C--; - } while (_vm->_map->getPass(var_A, var_C) > 17); - var_C++; - if (_vm->_map->getPass(var_A - 1, var_C) == 0) { - if (_vm->_map->getPass(var_A + 1, var_C) != 0) - var_A++; + gob2DestY--; + } while (_vm->_map->getPass(gob2DestX, gob2DestY) > 17); + gob2DestY++; + if (_vm->_map->getPass(gob2DestX - 1, gob2DestY) == 0) { + if (_vm->_map->getPass(gob2DestX + 1, gob2DestY) != 0) + gob2DestX++; } else - var_A--; - sub_197A6(var_A, var_C, 1); + gob2DestX--; + move(gob2DestX, gob2DestY, 1); } } else { - if (_vm->_map->getPass(var_A, var_C) > 17) { + if (_vm->_map->getPass(gob2DestX, gob2DestY) > 17) { do { - var_C++; - } while (_vm->_map->getPass(var_A, var_C) > 17); - var_C--; - if (_vm->_map->getPass(var_A - 1, var_C) == 0) { - if (_vm->_map->getPass(var_A + 1, var_C) != 0) - var_A++; + gob2DestY++; + } while (_vm->_map->getPass(gob2DestX, gob2DestY) > 17); + gob2DestY--; + if (_vm->_map->getPass(gob2DestX - 1, gob2DestY) == 0) { + if (_vm->_map->getPass(gob2DestX + 1, gob2DestY) != 0) + gob2DestX++; } else - var_A--; - sub_197A6(var_A, var_C, 1); + gob2DestX--; + move(gob2DestX, gob2DestY, 1); } } } diff --git a/engines/gob/imd.cpp b/engines/gob/imd.cpp new file mode 100644 index 0000000000..48789ea39a --- /dev/null +++ b/engines/gob/imd.cpp @@ -0,0 +1,972 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2004 Ivan Dubrov + * Copyright (C) 2004-2006 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/stdafx.h" +#include "common/endian.h" + +#include "gob/gob.h" +#include "gob/imd.h" +#include "gob/global.h" +#include "gob/util.h" +#include "gob/dataio.h" +#include "gob/draw.h" +#include "gob/game.h" +#include "gob/inter.h" +#include "gob/palanim.h" +#include "gob/sound.h" +#include "gob/video.h" + +namespace Gob { + +ImdPlayer::ImdPlayer(GobEngine *vm) : _vm(vm) { + _curImd = 0; + _curFile[0] = 0; + + _curX = 0; + _curY = 0; + + _frameDataSize = 0; + _vidBufferSize = 0; + _frameData = 0; + _vidBuffer = 0; + + _frontSurf = 21; + _backSurf = 21; + _frontMem = 0; + _frameDelay = 0; +} + +ImdPlayer::~ImdPlayer() { + if (_curImd) { + _curImd->surfDesc = 0; + delete[] _curImd->palette; + delete[] _curImd->framesPos; + delete[] _curImd->frameCoords; + } + delete[] _frameData; + delete[] _vidBuffer; + delete[] _frontMem; + delete _curImd; +} + +// flagsBit: 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; + + int32 byte_31449 = 0; + int32 byte_3144D = 0; + + buf[0] = 0; + strcpy(buf, path); + strcat(buf, ".IMD"); + + handle = _vm->_dataIO->openData(buf); + + if (handle < 0) { + warning("Can't open IMD \"%s\"", buf); + return 0; + } + + imdPtr = new Imd; + 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); + _vm->_dataIO->closeData(handle); + delete imdPtr; + return 0; + } + + imdPtr->surfDesc = surfDesc; + imdPtr->firstFramePos = imdPtr->curFrame; + +/* + imdPtr->field_3A = 0; + if ((imdPtr->verMin & 0x800) && ((flags & 3) != 3)) + imdPtr->field_3A = new Video::Color[256]; +*/ + + if (flags & 3) { + imdPtr->palette = new Video::Color[256]; + _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); + + _vm->_global->_setAllPalette = setAllPalBak; + _vm->_global->_pPaletteDesc->vgaPal = palBak; + } + + if ((imdPtr->verMin & 0xFF) >= 3) { + _vm->_dataIO->readData(handle, buf, 2); + imdPtr->stdX = READ_LE_UINT16(buf); + if (imdPtr->stdX > 1) { + warning("IMD ListI incorrect (%d)", imdPtr->stdX); + _vm->_dataIO->closeData(handle); + delete 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); + } 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) + imdPtr->framesPos = new int32[imdPtr->framesCount]; + } + + if (imdPtr->verMin & 0x8000) { + _vm->_dataIO->readData(handle, buf, 4); + byte_3144D = READ_LE_UINT32(buf); + } + + if (imdPtr->verMin & 0x4000) { // loc_29C4F + int16 word_3145B[3]; + + 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 (word_3145B[0] < 0) + word_3145B[0] = -word_3145B[0]; + if (word_3145B[2] < 0) + word_3145B[2] = -word_3145B[2]; + + warning("Imd Stub! Sound stuff!"); + return 0; + } // loc_29E43 + + if (imdPtr->verMin & 0x2000) { + _vm->_dataIO->readData(handle, buf, 2); + imdPtr->frameDataSize = READ_LE_UINT16(buf); + 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); + } + } 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; + } + 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->verMin & 0x8000) { + _vm->_dataIO->seekData(handle, byte_3144D, 0); + 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); + } + } 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"); + } + + return imdPtr; +} + +void ImdPlayer::finishImd(ImdPlayer::Imd *imdPtr) { + if (imdPtr == 0) + return; + +/* + if (dword_31345 != 0) { + _vm->_sound->stopSound(0); + dword_31345 = 0; + delete off_31461; + byte_31344 = 0; + } +*/ + + _vm->_dataIO->closeData(imdPtr->fileHandle); + + if (imdPtr->frameCoords != 0) + delete[] imdPtr->frameCoords; + if (imdPtr->palette != 0) + delete[] imdPtr->palette; + if (imdPtr->framesPos != 0) + delete[] imdPtr->framesPos; + + delete imdPtr; + imdPtr = 0; +} + +int8 ImdPlayer::openImd(const char *path, int16 x, int16 y, int16 repeat, int16 flags) { + int i; + int j; + const char *src; + byte *vidMem; + SurfaceDesc *surfDesc; + + if (path[0] != 0) { + if (!_curImd) + _curFile[0] = 0; + + src = strrchr(path, '\\'); + src = src == 0 ? path : src+1; + + if (strcmp(_curFile, src) != 0) { + closeImd(); + + _curImd = loadImdFile(path, 0, 2); + if (!_curImd) + return 0; + + _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 (_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); + } else { + _curImd->surfDesc = _vm->_draw->_spritesArray[_frontSurf]; + if ((x != -1) || (y != -1)) { + _curX = x != -1 ? x : _curX; + _curY = y != -1 ? y : _curY; + 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); + vidMem = _curImd->surfDesc->getVidMem(); + for (i = 0; i < _curImd->height; i++) + for (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; + setXY(_curImd, _curX, _curY); + } + _backSurf = (flags & 0x80) ? 20 : 21; + _curImd->surfDesc = _vm->_draw->_spritesArray[_backSurf]; + } + } + } + + if (!_curImd) + return 0; + + if (repeat == -1) { + closeImd(); + return 0; + } + + _curX = x != -1 ? x : _curX; + _curY = y != -1 ? y : _curY; + + WRITE_VAR(7, _curImd->framesCount); + + return 1; +} + +void ImdPlayer::closeImd(void) { + if (_curImd == 0) + return; + + _curImd->surfDesc = 0; + finishImd(_curImd); + + delete[] _frameData; + delete[] _vidBuffer; + _frameData = 0; + _vidBuffer = 0; + + _curImd = 0; +} + +void ImdPlayer::setXY(ImdPlayer::Imd *imdPtr, int16 x, int16 y) { + int i; + + if (imdPtr->stdX != -1) { + imdPtr->stdX = imdPtr->stdX - imdPtr->x + x; + imdPtr->stdY = imdPtr->stdY - imdPtr->y + y; + } + + if (imdPtr->frameCoords != 0) { + 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; + } + } + + _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, + SurfaceDesc *dest) { + if (!dest) + dest = _vm->_draw->_frontSurface; + + 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)) + _vm->_video->drawSprite(imdPtr->surfDesc, dest, + imdPtr->frameCoords[frame].left, imdPtr->frameCoords[frame].top, + imdPtr->frameCoords[frame].right, imdPtr->frameCoords[frame].bottom, + imdPtr->frameCoords[frame].left, imdPtr->frameCoords[frame].top, 1); + else if (imdPtr->stdX != -1) + _vm->_video->drawSprite(imdPtr->surfDesc, dest, + imdPtr->stdX, imdPtr->stdY, imdPtr->stdX + imdPtr->stdWidth - 1, + imdPtr->stdY + imdPtr->stdHeight - 1, x + imdPtr->stdX, + y + imdPtr->stdY, 1); + else + _vm->_video->drawSprite(imdPtr->surfDesc, dest, 0, 0, + imdPtr->width - 1, imdPtr->height - 1, x, y, 0); +} + +void ImdPlayer::renderframe(Imd *imdPtr) { + int i; + int16 imdX; + int16 imdY; + int16 imdW; + int16 imdH; + int16 sW; + uint16 pixCount, pixWritten; + uint8 type; + byte *imdVidMem; + byte *imdVidMemBak; + byte *dataPtr = 0; + byte *srcPtr = 0; + byte *srcPtrBak = 0; + + dataPtr = (byte *) _frameData; + imdX = imdPtr->x; + imdY = imdPtr->y; + imdW = imdPtr->width; + imdH = imdPtr->height; + sW = imdPtr->surfDesc->getWidth(); + imdVidMem = imdPtr->surfDesc->getVidMem() + sW * imdY + imdX; + + type = *dataPtr++; + srcPtr = dataPtr; + + if (type & 0x10) { + type ^= 0x10; + dataPtr++; // => 0x3C8 |_ palette + dataPtr += 48; // => 0x3C9 | stuff + } + + srcPtr = dataPtr; + if (type & 0x80) { + srcPtr = (byte *) _vidBuffer; + type &= 0x7F; + if ((type == 2) && (imdW == sW)) { + frameUncompressor(imdVidMem, dataPtr); + return; + } else + frameUncompressor(srcPtr, dataPtr); + } + + if (type == 2) { + for (i = 0; i < imdH; i++) { + memcpy(imdVidMem, srcPtr, imdW); + srcPtr += imdW; + imdVidMem += sW; + } + } else if (type == 1) { + imdVidMemBak = imdVidMem; + for (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; + memcpy(imdVidMem, srcPtr, pixCount); + imdVidMem += pixCount; + srcPtr += pixCount; + } else { + pixCount = (pixCount + 1) % 256; + pixWritten += pixCount; + imdVidMem += pixCount; + } + } + 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) { + 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; + memcpy(imdVidMem, srcPtr, pixCount); + memcpy(imdVidMem + sW, srcPtr, pixCount); + imdVidMem += pixCount; + srcPtr += pixCount; + } else { + pixCount = (pixCount + 1) % 256; + pixWritten += pixCount; + imdVidMem += pixCount; + } + } + srcPtrBak += sW + sW; + srcPtr = srcPtrBak; + } + } +} + +void ImdPlayer::frameUncompressor(byte *dest, byte *src) { + int i; + byte buf[4370]; + int16 chunkLength; + int16 frameLength; + uint16 bufPos1; + uint16 bufPos2; + uint16 tmp; + uint8 chunkBitField; + uint8 chunkCount; + bool mode; + + 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) + } + memset(buf, 32, bufPos1); + chunkCount = 1; + chunkBitField = 0; + + while (frameLength > 0) { + chunkCount--; + if (chunkCount == 0) { + tmp = *src++; + chunkCount = 8; + chunkBitField = tmp; + } + if (chunkBitField % 2) { + chunkBitField >>= 1; + buf[bufPos1] = *src; + *dest++ = *src++; + bufPos1 = (bufPos1 + 1) % 4096; + frameLength--; + continue; + } + chunkBitField >>= 1; + + tmp = READ_LE_UINT16(src); + src += 2; + chunkLength = ((tmp & 0xF00) >> 8) + 3; + + if ((mode && ((chunkLength & 0xFF) == 0x12)) || (!mode && (chunkLength == 0))) + chunkLength = *src++ + 0x12; + + bufPos2 = (tmp & 0xFF) + ((tmp >> 4) & 0x0F00); + 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)) { + memcpy(dest, buf + bufPos2, chunkLength); + dest += chunkLength; + memmove(buf + bufPos1, buf + bufPos2, 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; + } + } +} + +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 (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); + 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->_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) { + _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; +} + +} // End of namespace Gob diff --git a/engines/gob/imd.h b/engines/gob/imd.h new file mode 100644 index 0000000000..162aa5676e --- /dev/null +++ b/engines/gob/imd.h @@ -0,0 +1,111 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2004 Ivan Dubrov + * Copyright (C) 2004-2006 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef GOB_IMD_H +#define GOB_IMD_H + +#include "gob/video.h" + +namespace Gob { + +class ImdPlayer { +public: + +#include "common/pack-start.h" // START STRUCT PACKING + + struct ImdCoord { + int16 left; + int16 top; + int16 right; + int16 bottom; + }; + + struct Imd { + int16 fileHandle; + int16 verMin; + int16 framesCount; + int16 x; + int16 y; + int16 width; + int16 height; + int16 field_E; + int16 curFrame; + Video::Color *palette; + SurfaceDesc *surfDesc; + int32 *framesPos; + int32 firstFramePos; + int16 stdX; + int16 stdY; + int16 stdWidth; + int16 stdHeight; + int32 filePos; + ImdCoord *frameCoords; + int32 frameDataSize; + int32 vidBufferSize; + }; + +#include "common/pack-end.h" // END STRUCT PACKING + + Imd *_curImd; + byte _frontSurf; + int8 _backSurf; + byte *_frontMem; + int32 _frameDelay; + + 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 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(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; + + uint16 _frameDataSize; + uint16 _vidBufferSize; + byte *_frameData; + byte *_vidBuffer; + + GobEngine *_vm; +}; + +} // End of namespace Gob + +#endif // GOB_IMD_H diff --git a/engines/gob/init.cpp b/engines/gob/init.cpp index 21f8ed36f8..417fa7b52a 100644 --- a/engines/gob/init.cpp +++ b/engines/gob/init.cpp @@ -25,89 +25,52 @@ #include "common/endian.h" #include "gob/gob.h" -#include "gob/dataio.h" -#include "gob/global.h" #include "gob/init.h" -#include "gob/video.h" -#include "gob/sound.h" -#include "gob/timer.h" -#include "gob/sound.h" -#include "gob/game.h" -#include "gob/draw.h" +#include "gob/global.h" #include "gob/util.h" +#include "gob/dataio.h" #include "gob/cdrom.h" +#include "gob/draw.h" +#include "gob/game.h" +#include "gob/sound.h" +#include "gob/video.h" namespace Gob { -void game_start(void); - const char *Init::_fontNames[] = { "jeulet1.let", "jeulet2.let", "jeucar1.let", "jeumath.let" }; Init::Init(GobEngine *vm) : _vm(vm) { _palDesc = 0; } -void Init::findBestCfg(void) { - _vm->_global->_videoMode = VIDMODE_VGA; - _vm->_global->_useMouse = _vm->_global->_mousePresent; - _vm->_global->_soundFlags = MIDI_FLAG | SPEAKER_FLAG | BLASTER_FLAG | ADLIB_FLAG; -} - void Init::cleanup(void) { - if (_vm->_global->_debugFlag == 0) - _vm->_gtimer->disableTimer(); - _vm->_video->freeDriver(); - _vm->_video->freeSurfDesc(_vm->_global->_pPrimarySurfDesc); - _vm->_global->_pPrimarySurfDesc = 0; + _vm->_global->_primarySurfDesc = 0; _vm->_snd->speakerOff(); - - _vm->_dataio->closeDataFile(); - - if (_vm->_global->_sprAllocated != 0) - warning("cleanup: Allocated sprites left: %d", _vm->_global->_sprAllocated); - _vm->_snd->stopSound(0); + _vm->_dataIO->closeDataFile(); } void Init::initGame(char *totName) { int16 handle2; int16 handle; - int32 i; char *infBuf; char *infPtr; char *infEnd; - int16 j; char buffer[20]; int32 varsCount; -/* -src = byte ptr -2Eh -var_1A = word ptr -1Ah -var_18 = word ptr -18h -var_16 = dword ptr -16h -var_12 = word ptr -12h -var_10 = word ptr -10h -handle2 = word ptr -0Eh -fileHandle = word ptr -0Ch -numFromTot = word ptr -0Ah -memAvail = dword ptr -6 -memBlocks = word ptr -2*/ - - _vm->_global->_disableVideoCfg = 0x11; - _vm->_global->_disableMouseCfg = 0x15; - - soundVideo(1000, 1); - - handle2 = _vm->_dataio->openData("intro.stk"); + + initVideo(); + + handle2 = _vm->_dataIO->openData("intro.stk"); if (handle2 >= 0) { - _vm->_dataio->closeData(handle2); - _vm->_dataio->openDataFile("intro.stk"); + _vm->_dataIO->closeData(handle2); + _vm->_dataIO->openDataFile("intro.stk"); } _vm->_util->initInput(); - _vm->_video->setHandlers(); _vm->_video->initPrimary(_vm->_global->_videoMode); _vm->_global->_mouseXShift = 1; _vm->_global->_mouseYShift = 1; @@ -119,74 +82,71 @@ memBlocks = word ptr -2*/ _vm->_global->_inter_variablesSizes = 0; _palDesc = new Video::PalDesc; - if ((_vm->_global->_videoMode != 0x13) && (_vm->_global->_videoMode != 0x14)) - error("initGame: Only 0x13 or 0x14 video mode is supported!"); + _vm->validateVideoMode(_vm->_global->_videoMode); + _vm->_global->_setAllPalette = true; _palDesc->vgaPal = _vm->_draw->_vgaPalette; _palDesc->unused1 = _vm->_draw->_unusedPalette1; _palDesc->unused2 = _vm->_draw->_unusedPalette2; _vm->_video->setFullPalette(_palDesc); - for (i = 0; i < 8; i++) + for (int i = 0; i < 8; i++) _vm->_draw->_fonts[i] = 0; - handle = _vm->_dataio->openData("intro.inf"); + handle = _vm->_dataIO->openData("intro.inf"); if (handle < 0) { - for (i = 0; i < 4; i++) { - handle2 = _vm->_dataio->openData(_fontNames[i]); + for (int i = 0; i < 4; i++) { + handle2 = _vm->_dataIO->openData(_fontNames[i]); if (handle2 >= 0) { - _vm->_dataio->closeData(handle2); - _vm->_draw->_fonts[i] = - _vm->_util->loadFont(_fontNames[i]); + _vm->_dataIO->closeData(handle2); + _vm->_draw->_fonts[i] = _vm->_util->loadFont(_fontNames[i]); } } } else { - _vm->_dataio->closeData(handle); + _vm->_dataIO->closeData(handle); - infPtr = _vm->_dataio->getData("intro.inf"); + infPtr = _vm->_dataIO->getData("intro.inf"); infBuf = infPtr; - infEnd = infBuf + _vm->_dataio->getDataSize("intro.inf"); + infEnd = infBuf + _vm->_dataIO->getDataSize("intro.inf"); - for (i = 0; i < 4; i++, infPtr++) { - for (j = 0; infPtr < infEnd && *infPtr >= ' '; - j++, infPtr++) - buffer[j] = *infPtr; + for (int i = 0; i < 4; i++, infPtr++) { + int j; + for (j = 0; infPtr < infEnd && *infPtr >= ' '; j++, infPtr++) + buffer[j] = *infPtr; buffer[j] = 0; + strcat(buffer, ".let"); - handle2 = _vm->_dataio->openData(buffer); + handle2 = _vm->_dataIO->openData(buffer); if (handle2 >= 0) { - _vm->_dataio->closeData(handle2); + _vm->_dataIO->closeData(handle2); _vm->_draw->_fonts[i] = _vm->_util->loadFont(buffer); } - if (infPtr == infEnd) + if ((infPtr + 1) >= infEnd) break; infPtr++; - if (infPtr == infEnd) - break; } delete[] infBuf; } - if (totName != 0) { + if (totName) { strcpy(buffer, totName); strcat(buffer, ".tot"); - } else { + } else strcpy(buffer, _vm->_startTot); - } - handle = _vm->_dataio->openData(buffer); + handle = _vm->_dataIO->openData(buffer); if (handle >= 0) { // Get variables count - _vm->_dataio->seekData(handle, 0x2c, SEEK_SET); - _vm->_dataio->readData(handle, (char *)&varsCount, 2); + _vm->_dataIO->seekData(handle, 0x2C, SEEK_SET); + _vm->_dataIO->readData(handle, (char *) &varsCount, 2); varsCount = FROM_LE_16(varsCount); - _vm->_dataio->closeData(handle); + _vm->_dataIO->closeData(handle); _vm->_global->_inter_variables = new char[varsCount * 4]; _vm->_global->_inter_variablesSizes = new byte[varsCount * 4]; @@ -216,15 +176,15 @@ memBlocks = word ptr -2*/ } } - for (i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { if (_vm->_draw->_fonts[i] != 0) _vm->_util->freeFont(_vm->_draw->_fonts[i]); } delete _palDesc; - _vm->_dataio->closeDataFile(); + _vm->_dataIO->closeDataFile(); _vm->_video->initPrimary(-1); cleanup(); } -} // End of namespace Gob +} // End of namespace Gob diff --git a/engines/gob/init.h b/engines/gob/init.h index b0a7ed2f82..8d37740646 100644 --- a/engines/gob/init.h +++ b/engines/gob/init.h @@ -20,6 +20,7 @@ * $Id$ * */ + #ifndef GOB_INIT_H #define GOB_INIT_H @@ -29,10 +30,9 @@ namespace Gob { class Init { public: - void findBestCfg(void); void initGame(char *totFile); - virtual void soundVideo(int32 smallHeapSize, int16 flag) = 0; + virtual void initVideo() = 0; Init(GobEngine *vm); virtual ~Init() {}; @@ -47,7 +47,7 @@ protected: class Init_v1 : public Init { public: - virtual void soundVideo(int32 smallHeapSize, int16 flag); + virtual void initVideo(); Init_v1(GobEngine *vm); virtual ~Init_v1() {}; @@ -55,12 +55,12 @@ public: class Init_v2 : public Init_v1 { public: - virtual void soundVideo(int32 smallHeapSize, int16 flag); + virtual void initVideo(); Init_v2(GobEngine *vm); virtual ~Init_v2() {}; }; -} // End of namespace Gob +} // End of namespace Gob -#endif +#endif // GOB_INIT_H diff --git a/engines/gob/init_v1.cpp b/engines/gob/init_v1.cpp index c6c7481e22..48c425d301 100644 --- a/engines/gob/init_v1.cpp +++ b/engines/gob/init_v1.cpp @@ -27,8 +27,6 @@ #include "gob/gob.h" #include "gob/init.h" #include "gob/global.h" -#include "gob/timer.h" -#include "gob/video.h" #include "gob/draw.h" namespace Gob { @@ -36,18 +34,14 @@ namespace Gob { Init_v1::Init_v1(GobEngine *vm) : Init(vm) { } -void Init_v1::soundVideo(int32 smallHeap, int16 flag) { - if (_vm->_global->_videoMode != 0x13 && _vm->_global->_videoMode != 0x14 && _vm->_global->_videoMode != 0) - error("soundVideo: Video mode 0x%x is not supported!", - _vm->_global->_videoMode); +void Init_v1::initVideo() { + if (_vm->_global->_videoMode) + _vm->validateVideoMode(_vm->_global->_videoMode); _vm->_global->_mousePresent = 1; _vm->_global->_inVM = 0; - _vm->_global->_sprAllocated = 0; - _vm->_gtimer->enableTimer(); - if (_vm->_global->_videoMode == 0x13) _vm->_global->_colorCount = 256; @@ -55,7 +49,6 @@ void Init_v1::soundVideo(int32 smallHeap, int16 flag) { _vm->_global->_pPaletteDesc->vgaPal = _vm->_draw->_vgaPalette; _vm->_global->_pPaletteDesc->unused1 = _vm->_global->_unusedPalette1; _vm->_global->_pPaletteDesc->unused2 = _vm->_global->_unusedPalette2; - _vm->_global->_pPrimarySurfDesc = &_vm->_global->_primarySurfDesc; if (_vm->_global->_videoMode != 0) _vm->_video->initSurfDesc(_vm->_global->_videoMode, 320, 200, PRIMARY_SURFACE); diff --git a/engines/gob/init_v2.cpp b/engines/gob/init_v2.cpp index 1c5c8790fd..bd5be11987 100644 --- a/engines/gob/init_v2.cpp +++ b/engines/gob/init_v2.cpp @@ -27,39 +27,32 @@ #include "gob/gob.h" #include "gob/init.h" #include "gob/global.h" -#include "gob/timer.h" -#include "gob/video.h" #include "gob/draw.h" +#include "gob/video.h" namespace Gob { Init_v2::Init_v2(GobEngine *vm) : Init_v1(vm) { } -void Init_v2::soundVideo(int32 smallHeap, int16 flag) { - if (_vm->_global->_videoMode != 0x13 && _vm->_global->_videoMode != 0x14 && - _vm->_global->_videoMode != 0) - error("soundVideo: Video mode 0x%x is not supported!", - _vm->_global->_videoMode); +void Init_v2::initVideo() { + if (_vm->_global->_videoMode) + _vm->validateVideoMode(_vm->_global->_videoMode); - _vm->_draw->_frontSurface = &_vm->_global->_primarySurfDesc; - _vm->_video->initSurfDesc(_vm->_global->_videoMode, _vm->_video->_surfWidth, - _vm->_video->_surfHeight, 0x80); + _vm->_draw->_frontSurface = _vm->_global->_primarySurfDesc; + _vm->_video->initSurfDesc(_vm->_global->_videoMode, + _vm->_video->_surfWidth, _vm->_video->_surfHeight, 0x80); _vm->_global->_mousePresent = 1; _vm->_global->_inVM = 0; - _vm->_global->_sprAllocated = 0; - _vm->_gtimer->enableTimer(); - - if ((_vm->_platform == Common::kPlatformPC) || (_vm->_platform == Common::kPlatformMacintosh)) { - if ((_vm->_global->_videoMode == 0x13) || (_vm->_global->_videoMode == 0x14)) - _vm->_global->_colorCount = 256; - else - _vm->_global->_colorCount = 16; - } else - _vm->_global->_colorCount = 16; + _vm->_global->_colorCount = 16; + if (((_vm->_platform == Common::kPlatformPC) || + (_vm->_platform == Common::kPlatformMacintosh)) && + ((_vm->_global->_videoMode == 0x13) || + (_vm->_global->_videoMode == 0x14))) + _vm->_global->_colorCount = 256; _vm->_global->_pPaletteDesc = &_vm->_global->_paletteStruct; _vm->_global->_pPaletteDesc->vgaPal = _vm->_draw->_vgaPalette; diff --git a/engines/gob/inter.cpp b/engines/gob/inter.cpp index 7515be82a9..b0b800b25f 100644 --- a/engines/gob/inter.cpp +++ b/engines/gob/inter.cpp @@ -25,46 +25,58 @@ #include "common/endian.h" #include "gob/gob.h" -#include "gob/global.h" #include "gob/inter.h" +#include "gob/global.h" #include "gob/util.h" -#include "gob/scenery.h" -#include "gob/parse.h" -#include "gob/game.h" #include "gob/draw.h" -#include "gob/mult.h" -#include "gob/goblin.h" -#include "gob/cdrom.h" -#include "gob/map.h" +#include "gob/game.h" +#include "gob/parse.h" +#include "gob/scenery.h" +#include "gob/sound.h" namespace Gob { Inter::Inter(GobEngine *vm) : _vm(vm) { - int i; + _terminate = 0; + _break = false; - _noBusyWait = false; - _terminate = false; - _breakFlag = false; - - for (i = 0; i < 8; i++) - { + for (int i = 0; i < 8; i++) { _animPalLowIndex[i] = 0; _animPalHighIndex[i] = 0; _animPalDir[i] = 0; } - _soundEndTimeKey = 0; - _soundStopVal = 0; _breakFromLevel = 0; _nestLevel = 0; + _soundEndTimeKey = 0; + _soundStopVal = 0; + memset(_pasteBuf, 0, 300); memset(_pasteSizeBuf, 0, 300); _pastePos = 0; + + _noBusyWait = false; } -int16 Inter::load16(void) { - int16 tmp = (int16)READ_LE_UINT16(_vm->_global->_inter_execPtr); +void Inter::initControlVars(char full) { + *_nestLevel = 0; + *_breakFromLevel = -1; + + *_vm->_scenery->_pCaptureCounter = 0; + + _break = false; + _terminate = 0; + + if (full == 1) { + for (int i = 0; i < 8; i++) + _animPalDir[i] = 0; + _soundEndTimeKey = 0; + } +} + +int16 Inter::load16() { + int16 tmp = (int16) READ_LE_UINT16(_vm->_global->_inter_execPtr); _vm->_global->_inter_execPtr += 2; return tmp; } @@ -72,11 +84,10 @@ int16 Inter::load16(void) { char Inter::evalExpr(int16 *pRes) { byte token; -// _vm->_parse->printExpr(99); _vm->_parse->parseExpr(99, &token); - if (pRes == 0) + if (!pRes) return token; switch (token) { @@ -93,43 +104,102 @@ char Inter::evalExpr(int16 *pRes) { *pRes = 1; break; } + return token; } -char Inter::evalBoolResult() { +bool Inter::evalBoolResult() { byte token; _vm->_parse->printExpr(99); _vm->_parse->parseExpr(99, &token); - if (token == 24 || (token == 20 && _vm->_global->_inter_resVal != 0)) - return 1; + if ((token == 24) || ((token == 20) && _vm->_global->_inter_resVal)) + return true; else - return 0; + return false; +} + +void Inter::renewTimeInVars() { + struct tm *t; + time_t now = time(NULL); + + t = localtime(&now); + + WRITE_VAR(5, 1900 + t->tm_year); + WRITE_VAR(6, t->tm_mon + 1); + WRITE_VAR(7, 0); + WRITE_VAR(8, t->tm_mday); + WRITE_VAR(9, t->tm_hour); + WRITE_VAR(10, t->tm_min); + WRITE_VAR(11, t->tm_sec); +} + +void Inter::storeMouse() { + int16 x; + int16 y; + + x = _vm->_global->_inter_mouseX; + y = _vm->_global->_inter_mouseY; + _vm->_draw->adjustCoords(1, &x, &y); + + WRITE_VAR(2, x); + WRITE_VAR(3, y); + WRITE_VAR(4, _vm->_game->_mouseButtons); +} + +void Inter::storeKey(int16 key) { + WRITE_VAR(12, _vm->_util->getTimeKey() - _vm->_game->_startTimeKey); + + storeMouse(); + WRITE_VAR(1, _vm->_snd->_playingSound); + + if (key == 0x4800) + key = 0x0B; + else if (key == 0x5000) + key = 0x0A; + else if (key == 0x4D00) + key = 0x09; + else if (key == 0x4B00) + key = 0x08; + else if (key == 0x011B) + key = 0x1B; + else if (key == 0x0E08) + key = 0x19; + else if (key == 0x5300) + key = 0x1A; + else if ((key & 0xFF) != 0) + key &= 0xFF; + + WRITE_VAR(0, key); + + if (key != 0) + _vm->_util->clearKeyBuf(); } void Inter::funcBlock(int16 retFlag) { - char cmdCount; - int16 counter; + OpFuncParams params; byte cmd; byte cmd2; - if (_vm->_global->_inter_execPtr == 0) + params.retFlag = retFlag; + + if (!_vm->_global->_inter_execPtr) return; - _breakFlag = false; + _break = false; _vm->_global->_inter_execPtr++; - cmdCount = *_vm->_global->_inter_execPtr++; + params.cmdCount = *_vm->_global->_inter_execPtr++; _vm->_global->_inter_execPtr += 2; - if (cmdCount == 0) { + if (params.cmdCount == 0) { _vm->_global->_inter_execPtr = 0; return; } - int startaddr = _vm->_global->_inter_execPtr-_vm->_game->_totFileData; + int startaddr = _vm->_global->_inter_execPtr - _vm->_game->_totFileData; - counter = 0; + params.counter = 0; do { if (_terminate) break; @@ -154,37 +224,36 @@ void Inter::funcBlock(int16 retFlag) { { _vm->_util->longDelay(5000); } - } - // (end workaround) + } // End of workaround - cmd = (byte)*_vm->_global->_inter_execPtr; + cmd = (byte) *_vm->_global->_inter_execPtr; if ((cmd >> 4) >= 12) { cmd2 = 16 - (cmd >> 4); - cmd &= 0xf; + cmd &= 0xF; } else cmd2 = 0; _vm->_global->_inter_execPtr++; - counter++; + params.counter++; if (cmd2 == 0) cmd >>= 4; - if (executeFuncOpcode(cmd2, cmd, cmdCount, counter, retFlag)) + if (executeFuncOpcode(cmd2, cmd, params)) return; if (_vm->_quitRequested) break; - if (_breakFlag) { - if (retFlag != 2) + if (_break) { + if (params.retFlag != 2) break; if (*_breakFromLevel == -1) - _breakFlag = false; + _break = false; break; } - } while (counter != cmdCount); + } while (params.counter != params.cmdCount); _vm->_global->_inter_execPtr = 0; return; @@ -192,191 +261,21 @@ void Inter::funcBlock(int16 retFlag) { void Inter::callSub(int16 retFlag) { int16 block; - while (!_vm->_quitRequested && _vm->_global->_inter_execPtr != 0 && (char *)_vm->_global->_inter_execPtr != _vm->_game->_totFileData) { + + while (!_vm->_quitRequested && _vm->_global->_inter_execPtr && + (_vm->_global->_inter_execPtr != _vm->_game->_totFileData)) { + block = *_vm->_global->_inter_execPtr; - if (block == 1) { + if (block == 1) funcBlock(retFlag); - } else if (block == 2) { + else if (block == 2) _vm->_game->collisionsBlock(); - } + else + error("Unknown block type %d in Inter::callSub()", block); } - if ((char *)_vm->_global->_inter_execPtr == _vm->_game->_totFileData) - _terminate = true; -} - -void Inter::initControlVars(char full) { - int i; - - *_nestLevel = 0; - *_breakFromLevel = -1; - - *_vm->_scenery->_pCaptureCounter = 0; - - _breakFlag = false; - _terminate = false; - - if (full == 1) { - for (i = 0; i < 8; i++) - _animPalDir[i] = 0; - _soundEndTimeKey = 0; - } -} - -void Inter::renewTimeInVars(void) { - struct tm *t; - time_t now = time(NULL); - - t = localtime(&now); - - WRITE_VAR(5, 1900 + t->tm_year); - WRITE_VAR(6, t->tm_mon + 1); - WRITE_VAR(7, 0); - WRITE_VAR(8, t->tm_mday); - WRITE_VAR(9, t->tm_hour); - WRITE_VAR(10, t->tm_min); - WRITE_VAR(11, t->tm_sec); -} - -void Inter::manipulateMap(int16 xPos, int16 yPos, int16 item) { - for (int16 y = 0; y < _vm->_map->_mapHeight; y++) { - for (int16 x = 0; x < _vm->_map->_mapWidth; x++) { - if ((_vm->_map->_itemsMap[y][x] & 0xff) == item) { - _vm->_map->_itemsMap[y][x] &= 0xff00; - } else if (((_vm->_map->_itemsMap[y][x] & 0xff00) >> 8) - == item) { - _vm->_map->_itemsMap[y][x] &= 0xff; - } - } - } - - if (xPos < _vm->_map->_mapWidth - 1) { - if (yPos > 0) { - if ((_vm->_map->_itemsMap[yPos][xPos] & 0xff00) != 0 || - (_vm->_map->_itemsMap[yPos - 1][xPos] & 0xff00) != - 0 - || (_vm->_map->_itemsMap[yPos][xPos + - 1] & 0xff00) != 0 - || (_vm->_map->_itemsMap[yPos - 1][xPos + - 1] & 0xff00) != 0) { - - _vm->_map->_itemsMap[yPos][xPos] = - (_vm->_map->_itemsMap[yPos][xPos] & 0xff00) - + item; - - _vm->_map->_itemsMap[yPos - 1][xPos] = - (_vm->_map->_itemsMap[yPos - - 1][xPos] & 0xff00) + item; - - _vm->_map->_itemsMap[yPos][xPos + 1] = - (_vm->_map->_itemsMap[yPos][xPos + - 1] & 0xff00) + item; - - _vm->_map->_itemsMap[yPos - 1][xPos + 1] = - (_vm->_map->_itemsMap[yPos - 1][xPos + - 1] & 0xff00) + item; - } else { - _vm->_map->_itemsMap[yPos][xPos] = - (_vm->_map->_itemsMap[yPos][xPos] & 0xff) + - (item << 8); - - _vm->_map->_itemsMap[yPos - 1][xPos] = - (_vm->_map->_itemsMap[yPos - - 1][xPos] & 0xff) + (item << 8); - - _vm->_map->_itemsMap[yPos][xPos + 1] = - (_vm->_map->_itemsMap[yPos][xPos + - 1] & 0xff) + (item << 8); - - _vm->_map->_itemsMap[yPos - 1][xPos + 1] = - (_vm->_map->_itemsMap[yPos - 1][xPos + - 1] & 0xff) + (item << 8); - } - } else { - if ((_vm->_map->_itemsMap[yPos][xPos] & 0xff00) != 0 || - (_vm->_map->_itemsMap[yPos][xPos + 1] & 0xff00) != - 0) { - _vm->_map->_itemsMap[yPos][xPos] = - (_vm->_map->_itemsMap[yPos][xPos] & 0xff00) - + item; - - _vm->_map->_itemsMap[yPos][xPos + 1] = - (_vm->_map->_itemsMap[yPos][xPos + - 1] & 0xff00) + item; - } else { - _vm->_map->_itemsMap[yPos][xPos] = - (_vm->_map->_itemsMap[yPos][xPos] & 0xff) + - (item << 8); - - _vm->_map->_itemsMap[yPos][xPos + 1] = - (_vm->_map->_itemsMap[yPos][xPos + - 1] & 0xff) + (item << 8); - } - } - } else { - if (yPos > 0) { - if ((_vm->_map->_itemsMap[yPos][xPos] & 0xff00) != 0 || - (_vm->_map->_itemsMap[yPos - 1][xPos] & 0xff00) != - 0) { - _vm->_map->_itemsMap[yPos][xPos] = - (_vm->_map->_itemsMap[yPos][xPos] & 0xff00) - + item; - - _vm->_map->_itemsMap[yPos - 1][xPos] = - (_vm->_map->_itemsMap[yPos - - 1][xPos] & 0xff00) + item; - } else { - _vm->_map->_itemsMap[yPos][xPos] = - (_vm->_map->_itemsMap[yPos][xPos] & 0xff) + - (item << 8); - - _vm->_map->_itemsMap[yPos - 1][xPos] = - (_vm->_map->_itemsMap[yPos - - 1][xPos] & 0xff) + (item << 8); - } - } else { - if ((_vm->_map->_itemsMap[yPos][xPos] & 0xff00) != 0) { - _vm->_map->_itemsMap[yPos][xPos] = - (_vm->_map->_itemsMap[yPos][xPos] & 0xff00) - + item; - } else { - _vm->_map->_itemsMap[yPos][xPos] = - (_vm->_map->_itemsMap[yPos][xPos] & 0xff) + - (item << 8); - } - } - } - - if (item < 0 || item >= 20) - return; - - if (xPos > 1 && _vm->_map->getPass(xPos - 2, yPos) == 1) { - _vm->_map->_itemPoses[item].x = xPos - 2; - _vm->_map->_itemPoses[item].y = yPos; - _vm->_map->_itemPoses[item].orient = 4; - return; - } - - if (xPos < _vm->_map->_mapWidth - 2 && _vm->_map->getPass(xPos + 2, yPos) == 1) { - _vm->_map->_itemPoses[item].x = xPos + 2; - _vm->_map->_itemPoses[item].y = yPos; - _vm->_map->_itemPoses[item].orient = 0; - return; - } - - if (xPos < _vm->_map->_mapWidth - 1 && _vm->_map->getPass(xPos + 1, yPos) == 1) { - _vm->_map->_itemPoses[item].x = xPos + 1; - _vm->_map->_itemPoses[item].y = yPos; - _vm->_map->_itemPoses[item].orient = 0; - return; - } - - if (xPos > 0 && _vm->_map->getPass(xPos - 1, yPos) == 1) { - _vm->_map->_itemPoses[item].x = xPos - 1; - _vm->_map->_itemPoses[item].y = yPos; - _vm->_map->_itemPoses[item].orient = 4; - return; - } + if (_vm->_global->_inter_execPtr == _vm->_game->_totFileData) + _terminate = 1; } } // End of namespace Gob diff --git a/engines/gob/inter.h b/engines/gob/inter.h index e051f03c12..ba044c35ca 100644 --- a/engines/gob/inter.h +++ b/engines/gob/inter.h @@ -20,6 +20,7 @@ * $Id$ * */ + #ifndef GOB_INTERPRET_H #define GOB_INTERPRET_H @@ -37,343 +38,355 @@ namespace Gob { class Inter { public: - int16 _animPalLowIndex[8]; - int16 _animPalHighIndex[8]; - int16 _animPalDir[8]; - uint32 _soundEndTimeKey; - int16 _soundStopVal; - char _terminate; - char _breakFlag; + uint8 _terminate; + int16 *_breakFromLevel; int16 *_nestLevel; - int16 load16(void); - int16 peek16(char *ptr); - int32 peek32(char *ptr); - - char _pasteBuf[300]; - byte _pasteSizeBuf[300]; - int16 _pastePos; + uint32 _soundEndTimeKey; + int16 _soundStopVal; + void initControlVars(char full); + int16 load16(); char evalExpr(int16 *pRes); - char evalBoolResult(void); + bool evalBoolResult(); + void renewTimeInVars(); + void storeMouse(); + void storeKey(int16 key); + void funcBlock(int16 retFlag); void callSub(int16 retFlag); - void initControlVars(char full); - void renewTimeInVars(void); - void manipulateMap(int16 xPos, int16 yPos, int16 item); - virtual void checkSwitchTable(char **ppExec) = 0; + virtual int16 loadSound(int16 slot) = 0; - virtual void storeKey(int16 key) = 0; - virtual void storeMouse(void) = 0; - virtual void animPalette(void) = 0; + virtual void animPalette() = 0; Inter(GobEngine *vm); virtual ~Inter() {}; protected: - GobEngine *_vm; + struct OpFuncParams { + char cmdCount; + int16 counter; + int16 retFlag; + }; + struct OpGobParams { + int16 extraData; + int32 *retVarPtr; + Goblin::Gob_Object *objDesc; + }; + + bool _break; + + int16 _animPalLowIndex[8]; + int16 _animPalHighIndex[8]; + int16 _animPalDir[8]; + + char _pasteBuf[300]; + byte _pasteSizeBuf[300]; + int16 _pastePos; // The busy-wait detection in o1_keyFunc breaks fast scrolling in Ween bool _noBusyWait; - virtual void setupOpcodes(void) = 0; + GobEngine *_vm; + + virtual void setupOpcodes() = 0; virtual void executeDrawOpcode(byte i) = 0; - virtual bool executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, int16 &retFlag) = 0; - virtual void executeGoblinOpcode(int i, int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) = 0; + virtual bool executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms) = 0; + virtual void executeGoblinOpcode(int i, OpGobParams ¶ms) = 0; virtual const char *getOpcodeDrawDesc(byte i) = 0; virtual const char *getOpcodeFuncDesc(byte i, byte j) = 0; virtual const char *getOpcodeGoblinDesc(int i) = 0; - virtual void loadMult(void) = 0; - void o_drawNOP(void) {} - bool o_funcNOP(char &cmdCount, int16 &counter, int16 &retFlag) { return false; } - void o_gobNOP(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) {} + virtual void checkSwitchTable(char **ppExec) = 0; + + void o_drawNOP() {} + bool o_funcNOP(OpFuncParams ¶ms) { return false; } + void o_gobNOP(OpGobParams ¶ms) {} }; class Inter_v1 : public Inter { public: Inter_v1(GobEngine *vm); virtual ~Inter_v1() {}; - virtual void checkSwitchTable(char **ppExec); + virtual int16 loadSound(int16 slot); - virtual void storeKey(int16 key); - virtual void storeMouse(void); - virtual void animPalette(void); + virtual void animPalette(); protected: - typedef void (Inter_v1::*OpcodeDrawProcV1)(void); - typedef bool (Inter_v1::*OpcodeFuncProcV1)(char &, int16 &, int16 &); - typedef void (Inter_v1::*OpcodeGoblinProcV1)(int16 &, int32 *, Goblin::Gob_Object *); + typedef void (Inter_v1::*OpcodeDrawProcV1)(); + typedef bool (Inter_v1::*OpcodeFuncProcV1)(OpFuncParams &); + typedef void (Inter_v1::*OpcodeGoblinProcV1)(OpGobParams &); struct OpcodeDrawEntryV1 { OpcodeDrawProcV1 proc; const char *desc; - }; + }; struct OpcodeFuncEntryV1 { OpcodeFuncProcV1 proc; const char *desc; - }; + }; struct OpcodeGoblinEntryV1 { OpcodeGoblinProcV1 proc; const char *desc; - }; + }; const OpcodeDrawEntryV1 *_opcodesDrawV1; const OpcodeFuncEntryV1 *_opcodesFuncV1; const OpcodeGoblinEntryV1 *_opcodesGoblinV1; static const int _goblinFuncLookUp[][2]; - virtual void setupOpcodes(void); + virtual void setupOpcodes(); virtual void executeDrawOpcode(byte i); - virtual bool executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, int16 &retFlag); - virtual void executeGoblinOpcode(int i, int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); + virtual bool executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms); + virtual void executeGoblinOpcode(int i, OpGobParams ¶ms); virtual const char *getOpcodeDrawDesc(byte i); virtual const char *getOpcodeFuncDesc(byte i, byte j); virtual const char *getOpcodeGoblinDesc(int i); - virtual void loadMult(void); - - void o1_loadMult(void); - void o1_playMult(void); - void o1_freeMult(void); - void o1_initCursor(void); - void o1_initCursorAnim(void); - void o1_clearCursorAnim(void); - void o1_setRenderFlags(void); - void o1_loadAnim(void); - void o1_freeAnim(void); - void o1_updateAnim(void); - void o1_initMult(void); - void o1_multFreeMult(void); - void o1_animate(void); - void o1_multLoadMult(void); - void o1_storeParams(void); - void o1_getObjAnimSize(void); - void o1_loadStatic(void); - void o1_freeStatic(void); - void o1_renderStatic(void); - void o1_loadCurLayer(void); - void o1_playCDTrack(void); - void o1_getCDTrackPos(void); - void o1_stopCD(void); - void o1_loadFontToSprite(void); - void o1_freeFontToSprite(void); - bool o1_callSub(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_drawPrintText(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_call(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_callBool(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_loadCursor(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_repeatUntil(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_whileDo(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_evaluateStore(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_loadSpriteToPos(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_printText(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_loadTot(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_palLoad(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_keyFunc(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_capturePush(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_capturePop(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_animPalInit(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_drawOperations(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_renewTimeInVars(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_putPixel(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_createSprite(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_freeSprite(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_loadSpriteContent(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_copySprite(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_fillRect(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_drawLine(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_strToLong(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_invalidate(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_playSound(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_stopSound(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_playComposition(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_getFreeMem(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_checkData(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_prepareStr(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_insertStr(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_cutStr(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_strstr(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_istrlen(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_setMousePos(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_setFrameRate(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_loadFont(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_freeFont(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_readData(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_writeData(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_manageDataFile(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_setcmdCount(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_return(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_speakerOn(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_speakerOff(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_goblinFunc(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_returnTo(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_setBackDelta(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_loadSound(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_freeSoundSlot(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_waitEndPlay(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_animatePalette(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_animateCursor(char &cmdCount, int16 &counter, int16 &retFlag); - bool o1_blitCursor(char &cmdCount, int16 &counter, int16 &retFlag); - void o1_setState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_setCurFrame(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_setNextState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_setMultState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_setOrder(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_setActionStartState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_setCurLookDir(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_setType(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_setNoTick(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_setPickable(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_setXPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_setYPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_setDoAnim(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_setRelaxTime(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_setMaxTick(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_getState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_getCurFrame(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_getNextState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_getMultState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_getOrder(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_getActionStartState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_getCurLookDir(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_getType(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_getNoTick(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_getPickable(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_getObjMaxFrame(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_getXPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_getYPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_getDoAnim(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_getRelaxTime(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_getMaxTick(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_manipulateMap(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_getItem(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_manipulateMapIndirect(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_getItemIndirect(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_setPassMap(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_setGoblinPosH(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_getGoblinPosXH(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_getGoblinPosYH(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_setGoblinMultState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_setGoblinPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_setGoblinState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_setGoblinStateRedraw(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_setGoblinUnk14(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_setItemIdInPocket(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_setItemIndInPocket(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_getItemIdInPocket(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_getItemIndInPocket(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_setItemPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_decRelaxTime(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_getGoblinPosX(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_getGoblinPosY(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_clearPathExistence(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_setGoblinVisible(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_setGoblinInvisible(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_getObjectIntersect(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_getGoblinIntersect(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_loadObjects(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_freeObjects(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_animateObjects(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_drawObjects(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_loadMap(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_moveGoblin(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_switchGoblin(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_loadGoblin(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_writeTreatItem(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_moveGoblin0(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_setGoblinTarget(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_setGoblinObjectsPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o1_initGoblin(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); + + virtual void checkSwitchTable(char **ppExec); + + void o1_loadMult(); + void o1_playMult(); + void o1_freeMultKeys(); + void o1_initCursor(); + void o1_initCursorAnim(); + void o1_clearCursorAnim(); + void o1_setRenderFlags(); + void o1_loadAnim(); + void o1_freeAnim(); + void o1_updateAnim(); + void o1_initMult(); + void o1_freeMult(); + void o1_animate(); + void o1_loadMultObject(); + void o1_getAnimLayerInfo(); + void o1_getObjAnimSize(); + void o1_loadStatic(); + void o1_freeStatic(); + void o1_renderStatic(); + void o1_loadCurLayer(); + void o1_playCDTrack(); + void o1_getCDTrackPos(); + void o1_stopCD(); + void o1_loadFontToSprite(); + void o1_freeFontToSprite(); + bool o1_callSub(OpFuncParams ¶ms); + bool o1_printTotText(OpFuncParams ¶ms); + bool o1_loadCursor(OpFuncParams ¶ms); + bool o1_switch(OpFuncParams ¶ms); + bool o1_repeatUntil(OpFuncParams ¶ms); + bool o1_whileDo(OpFuncParams ¶ms); + bool o1_if(OpFuncParams ¶ms); + bool o1_evaluateStore(OpFuncParams ¶ms); + bool o1_loadSpriteToPos(OpFuncParams ¶ms); + bool o1_printText(OpFuncParams ¶ms); + bool o1_loadTot(OpFuncParams ¶ms); + bool o1_palLoad(OpFuncParams ¶ms); + bool o1_keyFunc(OpFuncParams ¶ms); + bool o1_capturePush(OpFuncParams ¶ms); + bool o1_capturePop(OpFuncParams ¶ms); + bool o1_animPalInit(OpFuncParams ¶ms); + bool o1_drawOperations(OpFuncParams ¶ms); + bool o1_setcmdCount(OpFuncParams ¶ms); + bool o1_return(OpFuncParams ¶ms); + bool o1_renewTimeInVars(OpFuncParams ¶ms); + bool o1_speakerOn(OpFuncParams ¶ms); + bool o1_speakerOff(OpFuncParams ¶ms); + bool o1_putPixel(OpFuncParams ¶ms); + bool o1_goblinFunc(OpFuncParams ¶ms); + bool o1_createSprite(OpFuncParams ¶ms); + bool o1_freeSprite(OpFuncParams ¶ms); + bool o1_returnTo(OpFuncParams ¶ms); + bool o1_loadSpriteContent(OpFuncParams ¶ms); + bool o1_copySprite(OpFuncParams ¶ms); + bool o1_fillRect(OpFuncParams ¶ms); + bool o1_drawLine(OpFuncParams ¶ms); + bool o1_strToLong(OpFuncParams ¶ms); + bool o1_invalidate(OpFuncParams ¶ms); + bool o1_setBackDelta(OpFuncParams ¶ms); + bool o1_playSound(OpFuncParams ¶ms); + bool o1_stopSound(OpFuncParams ¶ms); + bool o1_loadSound(OpFuncParams ¶ms); + bool o1_freeSoundSlot(OpFuncParams ¶ms); + bool o1_waitEndPlay(OpFuncParams ¶ms); + bool o1_playComposition(OpFuncParams ¶ms); + bool o1_getFreeMem(OpFuncParams ¶ms); + bool o1_checkData(OpFuncParams ¶ms); + bool o1_prepareStr(OpFuncParams ¶ms); + bool o1_insertStr(OpFuncParams ¶ms); + bool o1_cutStr(OpFuncParams ¶ms); + bool o1_strstr(OpFuncParams ¶ms); + bool o1_istrlen(OpFuncParams ¶ms); + bool o1_setMousePos(OpFuncParams ¶ms); + bool o1_setFrameRate(OpFuncParams ¶ms); + bool o1_animatePalette(OpFuncParams ¶ms); + bool o1_animateCursor(OpFuncParams ¶ms); + bool o1_blitCursor(OpFuncParams ¶ms); + bool o1_loadFont(OpFuncParams ¶ms); + bool o1_freeFont(OpFuncParams ¶ms); + bool o1_readData(OpFuncParams ¶ms); + bool o1_writeData(OpFuncParams ¶ms); + bool o1_manageDataFile(OpFuncParams ¶ms); + void o1_setState(OpGobParams ¶ms); + void o1_setCurFrame(OpGobParams ¶ms); + void o1_setNextState(OpGobParams ¶ms); + void o1_setMultState(OpGobParams ¶ms); + void o1_setOrder(OpGobParams ¶ms); + void o1_setActionStartState(OpGobParams ¶ms); + void o1_setCurLookDir(OpGobParams ¶ms); + void o1_setType(OpGobParams ¶ms); + void o1_setNoTick(OpGobParams ¶ms); + void o1_setPickable(OpGobParams ¶ms); + void o1_setXPos(OpGobParams ¶ms); + void o1_setYPos(OpGobParams ¶ms); + void o1_setDoAnim(OpGobParams ¶ms); + void o1_setRelaxTime(OpGobParams ¶ms); + void o1_setMaxTick(OpGobParams ¶ms); + void o1_getState(OpGobParams ¶ms); + void o1_getCurFrame(OpGobParams ¶ms); + void o1_getNextState(OpGobParams ¶ms); + void o1_getMultState(OpGobParams ¶ms); + void o1_getOrder(OpGobParams ¶ms); + void o1_getActionStartState(OpGobParams ¶ms); + void o1_getCurLookDir(OpGobParams ¶ms); + void o1_getType(OpGobParams ¶ms); + void o1_getNoTick(OpGobParams ¶ms); + void o1_getPickable(OpGobParams ¶ms); + void o1_getObjMaxFrame(OpGobParams ¶ms); + void o1_getXPos(OpGobParams ¶ms); + void o1_getYPos(OpGobParams ¶ms); + void o1_getDoAnim(OpGobParams ¶ms); + void o1_getRelaxTime(OpGobParams ¶ms); + void o1_getMaxTick(OpGobParams ¶ms); + void o1_manipulateMap(OpGobParams ¶ms); + void o1_getItem(OpGobParams ¶ms); + void o1_manipulateMapIndirect(OpGobParams ¶ms); + void o1_getItemIndirect(OpGobParams ¶ms); + void o1_setPassMap(OpGobParams ¶ms); + void o1_setGoblinPosH(OpGobParams ¶ms); + void o1_getGoblinPosXH(OpGobParams ¶ms); + void o1_getGoblinPosYH(OpGobParams ¶ms); + void o1_setGoblinMultState(OpGobParams ¶ms); + void o1_setGoblinUnk14(OpGobParams ¶ms); + void o1_setItemIdInPocket(OpGobParams ¶ms); + void o1_setItemIndInPocket(OpGobParams ¶ms); + void o1_getItemIdInPocket(OpGobParams ¶ms); + void o1_getItemIndInPocket(OpGobParams ¶ms); + void o1_setGoblinPos(OpGobParams ¶ms); + void o1_setGoblinState(OpGobParams ¶ms); + void o1_setGoblinStateRedraw(OpGobParams ¶ms); + void o1_decRelaxTime(OpGobParams ¶ms); + void o1_getGoblinPosX(OpGobParams ¶ms); + void o1_getGoblinPosY(OpGobParams ¶ms); + void o1_clearPathExistence(OpGobParams ¶ms); + void o1_setGoblinVisible(OpGobParams ¶ms); + void o1_setGoblinInvisible(OpGobParams ¶ms); + void o1_getObjectIntersect(OpGobParams ¶ms); + void o1_getGoblinIntersect(OpGobParams ¶ms); + void o1_setItemPos(OpGobParams ¶ms); + void o1_loadObjects(OpGobParams ¶ms); + void o1_freeObjects(OpGobParams ¶ms); + void o1_animateObjects(OpGobParams ¶ms); + void o1_drawObjects(OpGobParams ¶ms); + void o1_loadMap(OpGobParams ¶ms); + void o1_moveGoblin(OpGobParams ¶ms); + void o1_switchGoblin(OpGobParams ¶ms); + void o1_loadGoblin(OpGobParams ¶ms); + void o1_writeTreatItem(OpGobParams ¶ms); + void o1_moveGoblin0(OpGobParams ¶ms); + void o1_setGoblinTarget(OpGobParams ¶ms); + void o1_setGoblinObjectsPos(OpGobParams ¶ms); + void o1_initGoblin(OpGobParams ¶ms); + + void manipulateMap(int16 xPos, int16 yPos, int16 item); }; class Inter_v2 : public Inter_v1 { public: Inter_v2(GobEngine *vm); virtual ~Inter_v2() {}; - virtual void checkSwitchTable(char **ppExec); + virtual int16 loadSound(int16 search); - virtual void storeKey(int16 key); - virtual void storeMouse(void); - virtual void animPalette(void); + virtual void animPalette(); protected: - typedef void (Inter_v2::*OpcodeDrawProcV2)(void); - typedef bool (Inter_v2::*OpcodeFuncProcV2)(char &, int16 &, int16 &); - typedef void (Inter_v2::*OpcodeGoblinProcV2)(int16 &, int32 *, Goblin::Gob_Object *); + typedef void (Inter_v2::*OpcodeDrawProcV2)(); + typedef bool (Inter_v2::*OpcodeFuncProcV2)(OpFuncParams &); + typedef void (Inter_v2::*OpcodeGoblinProcV2)(OpGobParams &); struct OpcodeDrawEntryV2 { OpcodeDrawProcV2 proc; const char *desc; - }; + }; struct OpcodeFuncEntryV2 { OpcodeFuncProcV2 proc; const char *desc; - }; + }; struct OpcodeGoblinEntryV2 { OpcodeGoblinProcV2 proc; const char *desc; - }; + }; const OpcodeDrawEntryV2 *_opcodesDrawV2; const OpcodeFuncEntryV2 *_opcodesFuncV2; const OpcodeGoblinEntryV2 *_opcodesGoblinV2; static const int _goblinFuncLookUp[][2]; - virtual void setupOpcodes(void); + virtual void setupOpcodes(); virtual void executeDrawOpcode(byte i); - virtual bool executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, int16 &retFlag); - virtual void executeGoblinOpcode(int i, int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); + virtual bool executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms); + virtual void executeGoblinOpcode(int i, OpGobParams ¶ms); virtual const char *getOpcodeDrawDesc(byte i); virtual const char *getOpcodeFuncDesc(byte i, byte j); virtual const char *getOpcodeGoblinDesc(int i); - virtual void loadMult(void); - - void o2_drawStub(void) { error("Gob2 stub"); } - void o2_totSub(void); - void o2_switchTotSub(void); - void o2_stub0x54(void); - void o2_stub0x55(void); - void o2_scroll(void); - void o2_stub0x85(void); - bool o2_getFreeMem(char &cmdCount, int16 &counter, int16 &retFlag); - bool o2_readData(char &cmdCount, int16 &counter, int16 &retFlag); - bool o2_writeData(char &cmdCount, int16 &counter, int16 &retFlag); - bool o2_checkData(char &cmdCount, int16 &counter, int16 &retFlag); - bool o2_stopSound(char &cmdCount, int16 &counter, int16 &retFlag); - bool o2_createSprite(char &cmdCount, int16 &counter, int16 &retFlag); - bool o2_animPalInit(char &cmdCount, int16 &counter, int16 &retFlag); - bool o2_playSound(char &cmdCount, int16 &counter, int16 &retFlag); - bool o2_goblinFunc(char &cmdCount, int16 &counter, int16 &retFlag); - bool o2_evaluateStore(char &cmdCount, int16 &counter, int16 &retFlag); - bool o2_printText(char &cmdCount, int16 &counter, int16 &retFlag); - bool o2_palLoad(char &cmdCount, int16 &counter, int16 &retFlag); - bool o2_loadTot(char &cmdCount, int16 &counter, int16 &retFlag); - bool o2_freeSprite(char &cmdCount, int16 &counter, int16 &retFlag); - bool o2_loadSound(char &cmdCount, int16 &counter, int16 &retFlag); - void o2_copyVars(void); - void o2_pasteVars(void); - void o2_loadFontToSprite(void); - void o2_renderStatic(void); - void o2_loadMapObjects(void); - void o2_freeGoblins(void); - void o2_writeGoblinPos(void); - void o2_placeGoblin(void); - void o2_moveGoblin(void); - void o2_multSub(void); - void o2_setRenderFlags(void); - void o2_initMult(void); - void o2_getObjAnimSize(void); - void o2_loadCurLayer(void); - void o2_playCDTrack(void); - void o2_stopCD(void); - void o2_readLIC(void); - void o2_freeLIC(void); - void o2_getCDTrackPos(void); - void o2_playMult(void); - void o2_initCursor(void); - void o2_playImd(void); - void o2_initScreen(void); - void o2_setScrollOffset(void); - void o2_handleGoblins(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o2_loadInfogramesIns(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void o2_playInfogrames(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); + + virtual void checkSwitchTable(char **ppExec); + + void o2_playMult(); + void o2_setRenderFlags(); + void o2_multSub(); + void o2_initMult(); + void o2_loadMultObject(); + void o2_renderStatic(); + void o2_loadCurLayer(); + void o2_playCDTrack(); + void o2_waitCDTrackEnd(); + void o2_stopCD(); + void o2_readLIC(); + void o2_freeLIC(); + void o2_getCDTrackPos(); + void o2_loadFontToSprite(); + void o2_totSub(); + void o2_switchTotSub(); + void o2_copyVars(); + void o2_pasteVars(); + void o2_loadMapObjects(); + void o2_freeGoblins(); + void o2_moveGoblin(); + void o2_writeGoblinPos(); + void o2_stopGoblin(); + void o2_setGoblinState(); + void o2_placeGoblin(); + void o2_initScreen(); + void o2_scroll(); + void o2_setScrollOffset(); + void o2_playImd(); + void o2_getImdInfo(); + void o2_openItk(); + void o2_closeItk(); + void o2_setImdFrontSurf(); + void o2_resetImdFrontSurf(); + bool o2_evaluateStore(OpFuncParams ¶ms); + bool o2_printText(OpFuncParams ¶ms); + bool o2_animPalInit(OpFuncParams ¶ms); + bool o2_goblinFunc(OpFuncParams ¶ms); + bool o2_createSprite(OpFuncParams ¶ms); + bool o2_stopSound(OpFuncParams ¶ms); + bool o2_loadSound(OpFuncParams ¶ms); + bool o2_getFreeMem(OpFuncParams ¶ms); + bool o2_checkData(OpFuncParams ¶ms); + bool o2_readData(OpFuncParams ¶ms); + bool o2_writeData(OpFuncParams ¶ms); + void o2_loadInfogramesIns(OpGobParams ¶ms); + void o2_playInfogrames(OpGobParams ¶ms); + void o2_handleGoblins(OpGobParams ¶ms); }; class Inter_Bargon : public Inter_v2 { @@ -382,9 +395,9 @@ public: virtual ~Inter_Bargon() {}; protected: - typedef void (Inter_Bargon::*OpcodeDrawProcBargon)(void); - typedef bool (Inter_Bargon::*OpcodeFuncProcBargon)(char &, int16 &, int16 &); - typedef void (Inter_Bargon::*OpcodeGoblinProcBargon)(int16 &, int32 *, Goblin::Gob_Object *); + typedef void (Inter_Bargon::*OpcodeDrawProcBargon)(); + typedef bool (Inter_Bargon::*OpcodeFuncProcBargon)(OpFuncParams &); + typedef void (Inter_Bargon::*OpcodeGoblinProcBargon)(OpGobParams &); struct OpcodeDrawEntryBargon { OpcodeDrawProcBargon proc; const char *desc; @@ -402,26 +415,26 @@ protected: const OpcodeGoblinEntryBargon *_opcodesGoblinBargon; static const int _goblinFuncLookUp[][2]; - virtual void setupOpcodes(void); + virtual void setupOpcodes(); virtual void executeDrawOpcode(byte i); - virtual bool executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, int16 &retFlag); - virtual void executeGoblinOpcode(int i, int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); + virtual bool executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms); + virtual void executeGoblinOpcode(int i, OpGobParams ¶ms); virtual const char *getOpcodeDrawDesc(byte i); virtual const char *getOpcodeFuncDesc(byte i, byte j); virtual const char *getOpcodeGoblinDesc(int i); - void oBargon_intro0(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void oBargon_intro1(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void oBargon_intro2(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void oBargon_intro3(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void oBargon_intro4(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void oBargon_intro5(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void oBargon_intro6(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void oBargon_intro7(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void oBargon_intro8(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); - void oBargon_intro9(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc); + void oBargon_intro0(OpGobParams ¶ms); + void oBargon_intro1(OpGobParams ¶ms); + void oBargon_intro2(OpGobParams ¶ms); + void oBargon_intro3(OpGobParams ¶ms); + void oBargon_intro4(OpGobParams ¶ms); + void oBargon_intro5(OpGobParams ¶ms); + void oBargon_intro6(OpGobParams ¶ms); + void oBargon_intro7(OpGobParams ¶ms); + void oBargon_intro8(OpGobParams ¶ms); + void oBargon_intro9(OpGobParams ¶ms); }; -} // End of namespace Gob +} // End of namespace Gob -#endif +#endif // GOB_INTERPRET_H diff --git a/engines/gob/inter_bargon.cpp b/engines/gob/inter_bargon.cpp index 1e3ab00e76..069b93e66d 100644 --- a/engines/gob/inter_bargon.cpp +++ b/engines/gob/inter_bargon.cpp @@ -25,20 +25,16 @@ #include "common/endian.h" #include "gob/gob.h" -#include "gob/global.h" #include "gob/inter.h" +#include "gob/global.h" #include "gob/util.h" -#include "gob/scenery.h" -#include "gob/parse.h" -#include "gob/game.h" +#include "gob/dataio.h" #include "gob/draw.h" -#include "gob/mult.h" -#include "gob/goblin.h" -#include "gob/cdrom.h" +#include "gob/game.h" +#include "gob/imd.h" #include "gob/palanim.h" -#include "gob/anim.h" -#include "gob/music.h" -#include "gob/map.h" +#include "gob/sound.h" +#include "gob/video.h" namespace Gob { @@ -122,18 +118,18 @@ Inter_Bargon::Inter_Bargon(GobEngine *vm) : Inter_v2(vm) { setupOpcodes(); } -void Inter_Bargon::setupOpcodes(void) { +void Inter_Bargon::setupOpcodes() { static const OpcodeDrawEntryBargon opcodesDraw[256] = { /* 00 */ OPCODE(o1_loadMult), OPCODE(o2_playMult), - OPCODE(o1_freeMult), + OPCODE(o1_freeMultKeys), {NULL, ""}, /* 04 */ {NULL, ""}, {NULL, ""}, {NULL, ""}, - OPCODE(o2_initCursor), + OPCODE(o1_initCursor), /* 08 */ OPCODE(o1_initCursorAnim), OPCODE(o1_clearCursorAnim), @@ -151,12 +147,12 @@ void Inter_Bargon::setupOpcodes(void) { OPCODE(o2_multSub), /* 14 */ OPCODE(o2_initMult), - OPCODE(o1_multFreeMult), + OPCODE(o1_freeMult), OPCODE(o1_animate), - OPCODE(o1_multLoadMult), + OPCODE(o2_loadMultObject), /* 18 */ - OPCODE(o1_storeParams), - OPCODE(o2_getObjAnimSize), + OPCODE(o1_getAnimLayerInfo), + OPCODE(o1_getObjAnimSize), OPCODE(o1_loadStatic), OPCODE(o1_freeStatic), /* 1C */ @@ -166,7 +162,7 @@ void Inter_Bargon::setupOpcodes(void) { {NULL, ""}, /* 20 */ OPCODE(o2_playCDTrack), - OPCODE(o2_drawStub), + OPCODE(o2_waitCDTrackEnd), OPCODE(o2_stopCD), OPCODE(o2_readLIC), /* 24 */ @@ -230,8 +226,8 @@ void Inter_Bargon::setupOpcodes(void) { OPCODE(o2_moveGoblin), OPCODE(o2_writeGoblinPos), /* 54 */ - OPCODE(o2_stub0x54), - OPCODE(o2_stub0x55), + OPCODE(o2_stopGoblin), + OPCODE(o2_setGoblinState), OPCODE(o2_placeGoblin), {NULL, ""}, /* 58 */ @@ -290,12 +286,12 @@ void Inter_Bargon::setupOpcodes(void) { OPCODE(o2_setScrollOffset), OPCODE(o2_playImd), /* 84 */ - OPCODE(o2_drawStub), - OPCODE(o2_stub0x85), - OPCODE(o2_drawStub), - OPCODE(o2_drawStub), + OPCODE(o2_getImdInfo), + OPCODE(o2_openItk), + OPCODE(o2_closeItk), + OPCODE(o2_setImdFrontSurf), /* 88 */ - OPCODE(o2_drawStub), + OPCODE(o2_resetImdFrontSurf), {NULL, ""}, {NULL, ""}, {NULL, ""}, @@ -450,15 +446,15 @@ void Inter_Bargon::setupOpcodes(void) { /* 00 */ OPCODE(o1_callSub), OPCODE(o1_callSub), - OPCODE(o1_drawPrintText), + OPCODE(o1_printTotText), OPCODE(o1_loadCursor), /* 04 */ {NULL, ""}, - OPCODE(o1_call), + OPCODE(o1_switch), OPCODE(o1_repeatUntil), OPCODE(o1_whileDo), /* 08 */ - OPCODE(o1_callBool), + OPCODE(o1_if), OPCODE(o2_evaluateStore), OPCODE(o1_loadSpriteToPos), {NULL, ""}, @@ -470,8 +466,8 @@ void Inter_Bargon::setupOpcodes(void) { /* 10 */ {NULL, ""}, OPCODE(o2_printText), - OPCODE(o2_loadTot), - OPCODE(o2_palLoad), + OPCODE(o1_loadTot), + OPCODE(o1_palLoad), /* 14 */ OPCODE(o1_keyFunc), OPCODE(o1_capturePush), @@ -496,7 +492,7 @@ void Inter_Bargon::setupOpcodes(void) { OPCODE(o1_putPixel), OPCODE(o2_goblinFunc), OPCODE(o2_createSprite), - OPCODE(o2_freeSprite), + OPCODE(o1_freeSprite), /* 28 */ {NULL, ""}, {NULL, ""}, @@ -518,7 +514,7 @@ void Inter_Bargon::setupOpcodes(void) { OPCODE(o1_invalidate), OPCODE(o1_setBackDelta), /* 38 */ - OPCODE(o2_playSound), + OPCODE(o1_playSound), OPCODE(o2_stopSound), OPCODE(o2_loadSound), OPCODE(o1_freeSoundSlot), @@ -647,7 +643,8 @@ void Inter_Bargon::setupOpcodes(void) { } void Inter_Bargon::executeDrawOpcode(byte i) { - debugC(1, kDebugDrawOp, "opcodeDraw %d [0x%x] (%s)", i, i, getOpcodeDrawDesc(i)); + debugC(1, kDebugDrawOp, "opcodeDraw %d [0x%X] (%s)", + i, i, getOpcodeDrawDesc(i)); OpcodeDrawProcBargon op = _opcodesDrawBargon[i].proc; @@ -657,8 +654,9 @@ void Inter_Bargon::executeDrawOpcode(byte i) { (this->*op) (); } -bool Inter_Bargon::executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, int16 &retFlag) { - debugC(1, kDebugFuncOp, "opcodeFunc %d.%d [0x%x.0x%x] (%s)", i, j, i, j, getOpcodeFuncDesc(i, j)); +bool Inter_Bargon::executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms) { + debugC(1, kDebugFuncOp, "opcodeFunc %d.%d [0x%X.0x%X] (%s)", + i, j, i, j, getOpcodeFuncDesc(i, j)); if ((i > 4) || (j > 15)) { warning("unimplemented opcodeFunc: %d.%d", i, j); @@ -670,13 +668,14 @@ bool Inter_Bargon::executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &coun if (op == NULL) warning("unimplemented opcodeFunc: %d.%d", i, j); else - return (this->*op) (cmdCount, counter, retFlag); + return (this->*op) (params); return false; } -void Inter_Bargon::executeGoblinOpcode(int i, int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - debugC(1, kDebugGobOp, "opcodeGoblin %d [0x%x] (%s)", i, i, getOpcodeGoblinDesc(i)); +void Inter_Bargon::executeGoblinOpcode(int i, OpGobParams ¶ms) { + debugC(1, kDebugGobOp, "opcodeGoblin %d [0x%X] (%s)", + i, i, getOpcodeGoblinDesc(i)); OpcodeGoblinProcBargon op = NULL; @@ -695,7 +694,7 @@ void Inter_Bargon::executeGoblinOpcode(int i, int16 &extraData, int32 *retVarPtr warning("unimplemented opcodeGob: %d", i); } else - (this->*op) (extraData, retVarPtr, objDesc); + (this->*op) (params); } const char *Inter_Bargon::getOpcodeDrawDesc(byte i) { @@ -716,25 +715,21 @@ const char *Inter_Bargon::getOpcodeGoblinDesc(int i) { return ""; } -void Inter_Bargon::oBargon_intro0(int16 &extraData, int32 *retVarPtr, - Goblin::Gob_Object *objDesc) { - _vm->_game->playImd("scaa", 0, 160, 0, 92, 0, 1); +void Inter_Bargon::oBargon_intro0(OpGobParams ¶ms) { + _vm->_imdPlayer->play("scaa", 0, 160, 0, 92, 0, 1); } -void Inter_Bargon::oBargon_intro1(int16 &extraData, int32 *retVarPtr, - Goblin::Gob_Object *objDesc) { - _vm->_game->playImd("scaa", 0, 160, 0, -23, 1, 1); +void Inter_Bargon::oBargon_intro1(OpGobParams ¶ms) { + _vm->_imdPlayer->play("scaa", 0, 160, 0, -23, 1, 1); } -void Inter_Bargon::oBargon_intro2(int16 &extraData, int32 *retVarPtr, - Goblin::Gob_Object *objDesc) { +void Inter_Bargon::oBargon_intro2(OpGobParams ¶ms) { int i; int16 mouseX; int16 mouseY; int16 buttons; - Video::SurfaceDesc *surface; - Snd::SoundDesc *samples[4]; - int8 types[4] = { 2, 2, 2, 2 }; + SurfaceDesc *surface; + SoundDesc samples[4]; int16 comp[5] = { 0, 1, 2, 3, -1 }; static const char *sndFiles[] = {"1INTROII.snd", "2INTROII.snd", "1INTRO3.snd", "2INTRO3.snd"}; @@ -744,13 +739,13 @@ void Inter_Bargon::oBargon_intro2(int16 &extraData, int32 *retVarPtr, _vm->_video->drawPackedSprite("2ille4.ims", surface); _vm->_video->drawSprite(surface, _vm->_draw->_frontSurface, 0, 0, 319, 199, 320, 0, 0); _vm->_util->setScrollOffset(320, 0); - _vm->_palanim->fade(_vm->_global->_pPaletteDesc, -2, 0); + _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, -2, 0); _vm->_util->longDelay(1000); for (i = 320; i >= 0; i--) { _vm->_util->setScrollOffset(i, 0); if ((_vm->_game->checkKeys(&mouseX, &mouseY, &buttons, 0) == 0x11B) || _vm->_quitRequested) { - _vm->_palanim->fade(0, -2, 0); + _vm->_palAnim->fade(0, -2, 0); _vm->_video->clearSurf(_vm->_draw->_frontSurface); memset((char *) _vm->_draw->_vgaPalette, 0, 768); WRITE_VAR(4, buttons); @@ -761,44 +756,38 @@ void Inter_Bargon::oBargon_intro2(int16 &extraData, int32 *retVarPtr, } if (!_vm->_quitRequested) _vm->_util->setScrollOffset(0, 0); - _vm->_video->freeSurfDesc(surface); + surface = 0; if (VAR(57) == ((uint32) -1)) return; for (i = 0; i < 4; i++) - samples[i] = _vm->_game->loadSND(sndFiles[i], 0); - _vm->_snd->playComposition(comp, 0, samples, types, 4); + _vm->_snd->loadSample(samples[i], sndFiles[i]); + _vm->_snd->playComposition(comp, 0, samples, 4); _vm->_snd->waitEndPlay(true, false); - for (i = 0; i < 4; i++) - _vm->_snd->freeSoundDesc(samples[i]); - _vm->_palanim->fade(0, 0, 0); + _vm->_palAnim->fade(0, 0, 0); _vm->_video->clearSurf(_vm->_draw->_frontSurface); } -void Inter_Bargon::oBargon_intro3(int16 &extraData, int32 *retVarPtr, - Goblin::Gob_Object *objDesc) { - int i; - int j; +void Inter_Bargon::oBargon_intro3(OpGobParams ¶ms) { int16 mouseX; int16 mouseY; int16 buttons; Video::Color *palBak; - Snd::SoundDesc *samples[2]; - int8 types[2] = { 2, 2 }; + SoundDesc samples[2]; int16 comp[3] = { 0, 1, -1 }; char *palettes[4]; static const char *sndFiles[] = {"1INTROIV.snd", "2INTROIV.snd"}; static const char *palFiles[] = {"2ou2.clt", "2ou3.clt", "2ou4.clt", "2ou5.clt"}; - for (i = 0; i < 2; i++) - samples[i] = _vm->_game->loadSND(sndFiles[i], 0); - for (i = 0; i < 4; i++) - palettes[i] = _vm->_dataio->getData(palFiles[i]); + for (int i = 0; i < 2; i++) + _vm->_snd->loadSample(samples[i], sndFiles[i]); + for (int i = 0; i < 4; i++) + palettes[i] = _vm->_dataIO->getData(palFiles[i]); palBak = _vm->_global->_pPaletteDesc->vgaPal; - _vm->_snd->playComposition(comp, 0, samples, types, 2); - for (i = 0; i < 20; i++) { - for (j = 0; j < 4; j++) { + _vm->_snd->playComposition(comp, 0, samples, 2); + for (int i = 0; i < 20; i++) { + for (int j = 0; j < 4; j++) { _vm->_global->_pPaletteDesc->vgaPal = (Video::Color *) palettes[j]; _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); _vm->_util->longDelay(_vm->_util->getRandom(200)); @@ -806,7 +795,7 @@ void Inter_Bargon::oBargon_intro3(int16 &extraData, int32 *retVarPtr, if ((_vm->_game->checkKeys(&mouseX, &mouseY, &buttons, 0) == 0x11B) || _vm->_quitRequested) { _vm->_snd->stopSound(10); - _vm->_palanim->fade(0, -2, 0); + _vm->_palAnim->fade(0, -2, 0); _vm->_video->clearSurf(_vm->_draw->_frontSurface); memset((char *) _vm->_draw->_vgaPalette, 0, 768); WRITE_VAR(4, buttons); @@ -818,40 +807,32 @@ void Inter_Bargon::oBargon_intro3(int16 &extraData, int32 *retVarPtr, _vm->_snd->waitEndPlay(false, false); _vm->_global->_pPaletteDesc->vgaPal = palBak; - for (i = 0; i < 4; i++) + for (int i = 0; i < 4; i++) delete[] palettes[i]; - for (i = 0; i < 2; i++) - _vm->_snd->freeSoundDesc(samples[i]); } -void Inter_Bargon::oBargon_intro4(int16 &extraData, int32 *retVarPtr, - Goblin::Gob_Object *objDesc) { - _vm->_game->playImd("scba", 191, 54, 0, 0, 1, 1); +void Inter_Bargon::oBargon_intro4(OpGobParams ¶ms) { + _vm->_imdPlayer->play("scba", 191, 54, 0, 0, 1, 1); } -void Inter_Bargon::oBargon_intro5(int16 &extraData, int32 *retVarPtr, - Goblin::Gob_Object *objDesc) { - _vm->_game->playImd("scbb", 191, 54, 0, 0, 0, 1); +void Inter_Bargon::oBargon_intro5(OpGobParams ¶ms) { + _vm->_imdPlayer->play("scbb", 191, 54, 0, 0, 0, 1); } -void Inter_Bargon::oBargon_intro6(int16 &extraData, int32 *retVarPtr, - Goblin::Gob_Object *objDesc) { - _vm->_game->playImd("scbc", 191, 54, 0, 0, 0, 1); +void Inter_Bargon::oBargon_intro6(OpGobParams ¶ms) { + _vm->_imdPlayer->play("scbc", 191, 54, 0, 0, 0, 1); } -void Inter_Bargon::oBargon_intro7(int16 &extraData, int32 *retVarPtr, - Goblin::Gob_Object *objDesc) { - _vm->_game->playImd("scbf", 191, 54, 0, 0, 0, 1); +void Inter_Bargon::oBargon_intro7(OpGobParams ¶ms) { + _vm->_imdPlayer->play("scbf", 191, 54, 0, 0, 0, 1); } -void Inter_Bargon::oBargon_intro8(int16 &extraData, int32 *retVarPtr, - Goblin::Gob_Object *objDesc) { - _vm->_game->playImd("scbc", 191, 54, 0, 0, 0, 1); +void Inter_Bargon::oBargon_intro8(OpGobParams ¶ms) { + _vm->_imdPlayer->play("scbc", 191, 54, 0, 0, 0, 1); } -void Inter_Bargon::oBargon_intro9(int16 &extraData, int32 *retVarPtr, - Goblin::Gob_Object *objDesc) { - _vm->_game->playImd("scbd", 191, 54, 0, 0, 0, 1); +void Inter_Bargon::oBargon_intro9(OpGobParams ¶ms) { + _vm->_imdPlayer->play("scbd", 191, 54, 0, 0, 0, 1); } } // End of namespace Gob diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp index 045fa9007b..f6081a8fb2 100644 --- a/engines/gob/inter_v1.cpp +++ b/engines/gob/inter_v1.cpp @@ -23,22 +23,26 @@ #include "common/stdafx.h" #include "common/endian.h" +#include "common/file.h" #include "gob/gob.h" -#include "gob/global.h" #include "gob/inter.h" +#include "gob/global.h" #include "gob/util.h" -#include "gob/scenery.h" -#include "gob/parse.h" -#include "gob/game.h" +#include "gob/dataio.h" +#include "gob/music.h" +#include "gob/cdrom.h" #include "gob/draw.h" -#include "gob/mult.h" +#include "gob/game.h" #include "gob/goblin.h" -#include "gob/cdrom.h" -#include "gob/music.h" +#include "gob/inter.h" #include "gob/map.h" +#include "gob/mult.h" #include "gob/palanim.h" -#include "gob/anim.h" +#include "gob/parse.h" +#include "gob/scenery.h" +#include "gob/sound.h" +#include "gob/video.h" namespace Gob { @@ -122,12 +126,12 @@ Inter_v1::Inter_v1(GobEngine *vm) : Inter(vm) { setupOpcodes(); } -void Inter_v1::setupOpcodes(void) { +void Inter_v1::setupOpcodes() { static const OpcodeDrawEntryV1 opcodesDraw[256] = { /* 00 */ OPCODE(o1_loadMult), OPCODE(o1_playMult), - OPCODE(o1_freeMult), + OPCODE(o1_freeMultKeys), {NULL, ""}, /* 04 */ {NULL, ""}, @@ -151,11 +155,11 @@ void Inter_v1::setupOpcodes(void) { {NULL, ""}, /* 14 */ OPCODE(o1_initMult), - OPCODE(o1_multFreeMult), + OPCODE(o1_freeMult), OPCODE(o1_animate), - OPCODE(o1_multLoadMult), + OPCODE(o1_loadMultObject), /* 18 */ - OPCODE(o1_storeParams), + OPCODE(o1_getAnimLayerInfo), OPCODE(o1_getObjAnimSize), OPCODE(o1_loadStatic), OPCODE(o1_freeStatic), @@ -450,15 +454,15 @@ void Inter_v1::setupOpcodes(void) { /* 00 */ OPCODE(o1_callSub), OPCODE(o1_callSub), - OPCODE(o1_drawPrintText), + OPCODE(o1_printTotText), OPCODE(o1_loadCursor), /* 04 */ {NULL, ""}, - OPCODE(o1_call), + OPCODE(o1_switch), OPCODE(o1_repeatUntil), OPCODE(o1_whileDo), /* 08 */ - OPCODE(o1_callBool), + OPCODE(o1_if), OPCODE(o1_evaluateStore), OPCODE(o1_loadSpriteToPos), {NULL, ""}, @@ -642,12 +646,13 @@ void Inter_v1::setupOpcodes(void) { }; _opcodesDrawV1 = opcodesDraw; - _opcodesFuncV1 = opcodesFunc; // EGroupe + _opcodesFuncV1 = opcodesFunc; _opcodesGoblinV1 = opcodesGoblin; } void Inter_v1::executeDrawOpcode(byte i) { - debugC(1, kDebugDrawOp, "opcodeDraw %d [0x%x] (%s)", i, i, getOpcodeDrawDesc(i)); + debugC(1, kDebugDrawOp, "opcodeDraw %d [0x%X] (%s)", + i, i, getOpcodeDrawDesc(i)); OpcodeDrawProcV1 op = _opcodesDrawV1[i].proc; @@ -657,8 +662,9 @@ void Inter_v1::executeDrawOpcode(byte i) { (this->*op) (); } -bool Inter_v1::executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, int16 &retFlag) { - debugC(1, kDebugFuncOp, "opcodeFunc %d.%d [0x%x.0x%x] (%s)", i, j, i, j, getOpcodeFuncDesc(i, j)); +bool Inter_v1::executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms) { + debugC(1, kDebugFuncOp, "opcodeFunc %d.%d [0x%X.0x%X] (%s)", + i, j, i, j, getOpcodeFuncDesc(i, j)); if ((i > 4) || (j > 15)) { warning("unimplemented opcodeFunc: %d.%d", i, j); @@ -670,12 +676,13 @@ bool Inter_v1::executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, if (op == NULL) warning("unimplemented opcodeFunc: %d.%d", i, j); else - return (this->*op) (cmdCount, counter, retFlag); + return (this->*op) (params); return false; } -void Inter_v1::executeGoblinOpcode(int i, int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - debugC(1, kDebugGobOp, "opcodeGoblin %d [0x%x] (%s)", i, i, getOpcodeGoblinDesc(i)); +void Inter_v1::executeGoblinOpcode(int i, OpGobParams ¶ms) { + debugC(1, kDebugGobOp, "opcodeGoblin %d [0x%X] (%s)", + i, i, getOpcodeGoblinDesc(i)); OpcodeGoblinProcV1 op = NULL; @@ -692,7 +699,7 @@ void Inter_v1::executeGoblinOpcode(int i, int16 &extraData, int32 *retVarPtr, Go _vm->_global->_inter_execPtr += cmd * 2; } else - (this->*op) (extraData, retVarPtr, objDesc); + (this->*op) (params); } const char *Inter_v1::getOpcodeDrawDesc(byte i) { @@ -714,7 +721,6 @@ const char *Inter_v1::getOpcodeGoblinDesc(int i) { } void Inter_v1::checkSwitchTable(char **ppExec) { - int i; int16 len; int32 value; bool found; @@ -727,7 +733,7 @@ void Inter_v1::checkSwitchTable(char **ppExec) { len = (int8) *_vm->_global->_inter_execPtr++; while (len != -5) { - for (i = 0; i < len; i++) { + for (int i = 0; i < len; i++) { evalExpr(0); if (_terminate) @@ -742,7 +748,8 @@ void Inter_v1::checkSwitchTable(char **ppExec) { if (found) *ppExec = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; found = false; len = (int8) *_vm->_global->_inter_execPtr++; } @@ -754,150 +761,33 @@ void Inter_v1::checkSwitchTable(char **ppExec) { if (notFound) *ppExec = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; -} - -bool Inter_v1::o1_setMousePos(char &cmdCount, int16 &counter, int16 &retFlag) { - _vm->_global->_inter_mouseX = _vm->_parse->parseValExpr(); - _vm->_global->_inter_mouseY = _vm->_parse->parseValExpr(); - if (_vm->_global->_useMouse != 0) - _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY); - return false; -} - -bool Inter_v1::o1_evaluateStore(char &cmdCount, int16 &counter, int16 &retFlag) { - char *savedPos; - int16 token; - int16 result; - int16 varOff; - - savedPos = _vm->_global->_inter_execPtr; - varOff = _vm->_parse->parseVarIndex(); - token = evalExpr(&result); - switch (savedPos[0]) { - case 23: - case 26: - WRITE_VAR_OFFSET(varOff, _vm->_global->_inter_resVal); - break; - - case 25: - case 28: - if (token == 20) - WRITE_VARO_UINT8(varOff, result); - else - WRITE_VARO_STR(varOff, _vm->_global->_inter_resStr); - break; - - } - return false; -} - -bool Inter_v1::o1_capturePush(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 left; - int16 top; - int16 width; - int16 height; - - left = _vm->_parse->parseValExpr(); - top = _vm->_parse->parseValExpr(); - width = _vm->_parse->parseValExpr(); - height = _vm->_parse->parseValExpr(); - _vm->_game->capturePush(left, top, width, height); - (*_vm->_scenery->_pCaptureCounter)++; - return false; -} - -bool Inter_v1::o1_capturePop(char &cmdCount, int16 &counter, int16 &retFlag) { - if (*_vm->_scenery->_pCaptureCounter != 0) { - (*_vm->_scenery->_pCaptureCounter)--; - _vm->_game->capturePop(1); - } - return false; -} - -bool Inter_v1::o1_printText(char &cmdCount, int16 &counter, int16 &retFlag) { - char buf[60]; - int16 i; - - _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); - _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); - - _vm->_draw->_backColor = _vm->_parse->parseValExpr(); - _vm->_draw->_frontColor = _vm->_parse->parseValExpr(); - _vm->_draw->_fontIndex = _vm->_parse->parseValExpr(); - _vm->_draw->_destSurface = 21; - _vm->_draw->_textToPrint = buf; - _vm->_draw->_transparency = 0; - - if (_vm->_draw->_backColor >= 16) { - _vm->_draw->_backColor = 0; - _vm->_draw->_transparency = 1; - } - - do { - for (i = 0; *_vm->_global->_inter_execPtr != '.' && (byte)*_vm->_global->_inter_execPtr != 200; - i++, _vm->_global->_inter_execPtr++) { - buf[i] = *_vm->_global->_inter_execPtr; - } - - if ((byte)*_vm->_global->_inter_execPtr != 200) { - _vm->_global->_inter_execPtr++; - switch (*_vm->_global->_inter_execPtr) { - case 23: - case 26: - sprintf(buf + i, "%d", VAR_OFFSET(_vm->_parse->parseVarIndex())); - break; - - case 25: - case 28: - sprintf(buf + i, "%s", GET_VARO_STR(_vm->_parse->parseVarIndex())); - break; - } - _vm->_global->_inter_execPtr++; - } else { - buf[i] = 0; - } - _vm->_draw->spriteOperation(DRAW_PRINTTEXT); - } while ((byte)*_vm->_global->_inter_execPtr != 200); - _vm->_global->_inter_execPtr++; - - return false; + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; } -bool Inter_v1::o1_animPalInit(char &cmdCount, int16 &counter, int16 &retFlag) { - _animPalDir[0] = load16(); - _animPalLowIndex[0] = _vm->_parse->parseValExpr(); - _animPalHighIndex[0] = _vm->_parse->parseValExpr(); - return false; +void Inter_v1::o1_loadMult() { + _vm->_mult->loadMult(load16()); } -void Inter_v1::o1_loadMult(void) { - int16 resId; - - resId = load16(); - _vm->_mult->loadMult(resId); -} - -void Inter_v1::o1_playMult(void) { +void Inter_v1::o1_playMult() { int16 checkEscape; checkEscape = load16(); _vm->_mult->playMult(VAR(57), -1, checkEscape, 0); } -void Inter_v1::o1_freeMult(void) { - load16(); // unused +void Inter_v1::o1_freeMultKeys() { + load16(); _vm->_mult->freeMultKeys(); } -void Inter_v1::o1_initCursor(void) { +void Inter_v1::o1_initCursor() { int16 width; int16 height; int16 count; - int16 i; - _vm->_draw->_cursorXDeltaVar = _vm->_parse->parseVarIndex(); - _vm->_draw->_cursorYDeltaVar = _vm->_parse->parseVarIndex(); + _vm->_draw->_cursorHotspotXVar = _vm->_parse->parseVarIndex() / 4; + _vm->_draw->_cursorHotspotYVar = _vm->_parse->parseVarIndex() / 4; width = load16(); if (width < 16) @@ -907,16 +797,19 @@ void Inter_v1::o1_initCursor(void) { if (height < 16) height = 16; + _vm->_draw->adjustCoords(0, &width, &height); + count = load16(); if (count < 2) count = 2; - if (width != _vm->_draw->_cursorWidth || height != _vm->_draw->_cursorHeight || - _vm->_draw->_cursorSprites->width != width * count) { + if ((width != _vm->_draw->_cursorWidth) || + (height != _vm->_draw->_cursorHeight) || + (_vm->_draw->_cursorSprites->getWidth() != (width * count))) { - _vm->_video->freeSurfDesc(_vm->_draw->_cursorSprites); - _vm->_draw->_spritesArray[23] = 0; - _vm->_video->freeSurfDesc(_vm->_draw->_scummvmCursor); + _vm->_draw->freeSprite(23); + _vm->_draw->_cursorSprites = 0; + _vm->_draw->_cursorSpritesBack = 0; _vm->_draw->_scummvmCursor = 0; _vm->_draw->_cursorWidth = width; @@ -930,15 +823,17 @@ void Inter_v1::o1_initCursor(void) { if (count > 0x80) count -= 0x80; - _vm->_draw->_cursorSprites = - _vm->_video->initSurfDesc(_vm->_global->_videoMode, _vm->_draw->_cursorWidth * count, - _vm->_draw->_cursorHeight, 2); - _vm->_draw->_spritesArray[23] = _vm->_draw->_cursorSprites; + _vm->_draw->initSpriteSurf(23, _vm->_draw->_cursorWidth * count, + _vm->_draw->_cursorHeight, 2); + _vm->_draw->_cursorSpritesBack = _vm->_draw->_spritesArray[23]; + _vm->_draw->_cursorSprites = _vm->_draw->_cursorSpritesBack; _vm->_draw->_scummvmCursor = - _vm->_video->initSurfDesc(_vm->_global->_videoMode, _vm->_draw->_cursorWidth, - _vm->_draw->_cursorHeight, SCUMMVM_CURSOR); - for (i = 0; i < 40; i++) { + _vm->_video->initSurfDesc(_vm->_global->_videoMode, + _vm->_draw->_cursorWidth, _vm->_draw->_cursorHeight, + SCUMMVM_CURSOR); + + for (int i = 0; i < 40; i++) { _vm->_draw->_cursorAnimLow[i] = -1; _vm->_draw->_cursorAnimDelays[i] = 0; _vm->_draw->_cursorAnimHigh[i] = 0; @@ -947,7 +842,7 @@ void Inter_v1::o1_initCursor(void) { } } -void Inter_v1::o1_initCursorAnim(void) { +void Inter_v1::o1_initCursorAnim() { int16 ind; _vm->_draw->_showCursor = 3; @@ -957,7 +852,7 @@ void Inter_v1::o1_initCursorAnim(void) { _vm->_draw->_cursorAnimDelays[ind] = load16(); } -void Inter_v1::o1_clearCursorAnim(void) { +void Inter_v1::o1_clearCursorAnim() { int16 ind; _vm->_draw->_showCursor = 0; @@ -967,672 +862,19 @@ void Inter_v1::o1_clearCursorAnim(void) { _vm->_draw->_cursorAnimDelays[ind] = 0; } -bool Inter_v1::o1_drawOperations(char &cmdCount, int16 &counter, int16 &retFlag) { - byte cmd; - - cmd = *_vm->_global->_inter_execPtr++; - - executeDrawOpcode(cmd); - - return false; -} - -bool Inter_v1::o1_getFreeMem(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 freeVar; - int16 maxFreeVar; - - freeVar = _vm->_parse->parseVarIndex(); - maxFreeVar = _vm->_parse->parseVarIndex(); - - // HACK - WRITE_VAR_OFFSET(freeVar, 1000000); - WRITE_VAR_OFFSET(maxFreeVar, 1000000); - return false; -} - -bool Inter_v1::o1_manageDataFile(char &cmdCount, int16 &counter, int16 &retFlag) { - evalExpr(0); - - if (_vm->_global->_inter_resStr[0] != 0) - _vm->_dataio->openDataFile(_vm->_global->_inter_resStr); - else - _vm->_dataio->closeDataFile(); - return false; -} - -bool Inter_v1::o1_writeData(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 offset; - int16 handle; - int16 size; - int16 dataVar; - int16 retSize; - - // FIXME: This code tries to write to a file. But this is not portable - // as datafiles might not be writeable. So we should determine when - // precisely this function is used, and see if we can either change it - // to a no-op, or use the SaveFileManager instead. If we use savefiles, - // then corresponding read etc. file calls would have to be adapted, too. - - evalExpr(0); - dataVar = _vm->_parse->parseVarIndex(); - size = _vm->_parse->parseValExpr(); - offset = _vm->_parse->parseValExpr(); - - WRITE_VAR(1, 1); - handle = _vm->_dataio->openData(_vm->_global->_inter_resStr, Common::File::kFileWriteMode); - - if (handle < 0) - return false; - - if (offset < 0) { - _vm->_dataio->seekData(handle, -offset - 1, 2); - } else { - _vm->_dataio->seekData(handle, offset, 0); - } - - retSize = _vm->_dataio->file_getHandle(handle)->write(_vm->_global->_inter_variables + dataVar, size); - - if (retSize == size) - WRITE_VAR(1, 0); - - _vm->_dataio->closeData(handle); - return false; -} - -bool Inter_v1::o1_checkData(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 handle; - int16 varOff; - - evalExpr(0); - varOff = _vm->_parse->parseVarIndex(); - handle = _vm->_dataio->openData(_vm->_global->_inter_resStr); - - WRITE_VAR_OFFSET(varOff, handle); - if (handle >= 0) - _vm->_dataio->closeData(handle); - else - warning("File \"%s\" not found", _vm->_global->_inter_resStr); - return false; -} - -bool Inter_v1::o1_readData(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 retSize; - int16 size; - int16 dataVar; - int16 offset; - int16 handle; - char buf[4]; - - evalExpr(0); - dataVar = _vm->_parse->parseVarIndex(); - size = _vm->_parse->parseValExpr(); - offset = _vm->_parse->parseValExpr(); - - if (_vm->_game->_extHandle >= 0) - _vm->_dataio->closeData(_vm->_game->_extHandle); - - WRITE_VAR(1, 1); - handle = _vm->_dataio->openData(_vm->_global->_inter_resStr); - if (handle >= 0) { - _vm->_draw->animateCursor(4); - if (offset < 0) - _vm->_dataio->seekData(handle, -offset - 1, 2); - else - _vm->_dataio->seekData(handle, offset, 0); - - if (((dataVar >> 2) == 59) && (size == 4)) { - retSize = _vm->_dataio->readData(handle, buf, 4); - WRITE_VAR(59, READ_LE_UINT32(buf)); - } else - retSize = _vm->_dataio->readData(handle, _vm->_global->_inter_variables + dataVar, size); - _vm->_dataio->closeData(handle); - - if (retSize == size) - WRITE_VAR(1, 0); - } - - if (_vm->_game->_extHandle >= 0) - _vm->_game->_extHandle = _vm->_dataio->openData(_vm->_game->_curExtFile); - return false; -} - -bool Inter_v1::o1_loadFont(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 index; - - evalExpr(0); - index = load16(); - - if (_vm->_draw->_fonts[index] != 0) - _vm->_util->freeFont(_vm->_draw->_fonts[index]); - - _vm->_draw->animateCursor(4); - if (_vm->_game->_extHandle >= 0) - _vm->_dataio->closeData(_vm->_game->_extHandle); - - _vm->_draw->_fonts[index] = _vm->_util->loadFont(_vm->_global->_inter_resStr); - - if (_vm->_game->_extHandle >= 0) - _vm->_game->_extHandle = _vm->_dataio->openData(_vm->_game->_curExtFile); - return false; -} - -bool Inter_v1::o1_freeFont(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 index; - - index = load16(); - if (_vm->_draw->_fonts[index] != 0) - _vm->_util->freeFont(_vm->_draw->_fonts[index]); - - _vm->_draw->_fonts[index] = 0; - return false; -} - -bool Inter_v1::o1_prepareStr(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 var; - - var = _vm->_parse->parseVarIndex(); - _vm->_util->prepareStr(GET_VARO_STR(var)); - _vm->_global->writeVarSizeStr(var, strlen(GET_VARO_STR(var))); - return false; -} - -bool Inter_v1::o1_insertStr(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 pos; - int16 strVar; - - strVar = _vm->_parse->parseVarIndex(); - evalExpr(0); - pos = _vm->_parse->parseValExpr(); - _vm->_util->insertStr(_vm->_global->_inter_resStr, GET_VARO_STR(strVar), pos); - _vm->_global->writeVarSizeStr(strVar, strlen(GET_VARO_STR(strVar))); - return false; -} - -bool Inter_v1::o1_cutStr(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 var; - int16 pos; - int16 size; - - var = _vm->_parse->parseVarIndex(); - pos = _vm->_parse->parseValExpr(); - size = _vm->_parse->parseValExpr(); - _vm->_util->cutFromStr(GET_VARO_STR(var), pos, size); - return false; -} - -bool Inter_v1::o1_strstr(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 strVar; - int16 resVar; - int16 pos; - - strVar = _vm->_parse->parseVarIndex(); - evalExpr(0); - resVar = _vm->_parse->parseVarIndex(); - - char *res = strstr(GET_VARO_STR(strVar), _vm->_global->_inter_resStr); - pos = res ? (res - (GET_VARO_STR(strVar))) : -1; - WRITE_VAR_OFFSET(resVar, pos); - return false; -} - -bool Inter_v1::o1_setFrameRate(char &cmdCount, int16 &counter, int16 &retFlag) { - _vm->_util->setFrameRate(_vm->_parse->parseValExpr()); - return false; -} - -bool Inter_v1::o1_istrlen(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 len; - int16 var; - - var = _vm->_parse->parseVarIndex(); - len = strlen(GET_VARO_STR(var)); - var = _vm->_parse->parseVarIndex(); - - WRITE_VAR_OFFSET(var, len); - return false; -} - -bool Inter_v1::o1_strToLong(char &cmdCount, int16 &counter, int16 &retFlag) { - char str[20]; - int16 strVar; - int16 destVar; - int32 res; - - strVar = _vm->_parse->parseVarIndex(); - strcpy(str, GET_VARO_STR(strVar)); - res = atol(str); - - destVar = _vm->_parse->parseVarIndex(); - WRITE_VAR_OFFSET(destVar, res); - return false; -} - -bool Inter_v1::o1_invalidate(char &cmdCount, int16 &counter, int16 &retFlag) { - warning("invalidate: 'bugged' function"); - _vm->_draw->_destSurface = load16(); - _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); - _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); - _vm->_draw->_spriteRight = _vm->_parse->parseValExpr(); - _vm->_draw->_frontColor = _vm->_parse->parseValExpr(); - _vm->_draw->spriteOperation(DRAW_INVALIDATE); - return false; -} - -bool Inter_v1::o1_loadSpriteContent(char &cmdCount, int16 &counter, int16 &retFlag) { - _vm->_draw->_spriteLeft = load16(); - _vm->_draw->_destSurface = load16(); - _vm->_draw->_transparency = load16(); - _vm->_draw->_destSpriteX = 0; - _vm->_draw->_destSpriteY = 0; - _vm->_draw->spriteOperation(DRAW_LOADSPRITE); - return false; -} - -bool Inter_v1::o1_copySprite(char &cmdCount, int16 &counter, int16 &retFlag) { - _vm->_draw->_sourceSurface = load16(); - _vm->_draw->_destSurface = load16(); - - _vm->_draw->_spriteLeft = _vm->_parse->parseValExpr(); - _vm->_draw->_spriteTop = _vm->_parse->parseValExpr(); - _vm->_draw->_spriteRight = _vm->_parse->parseValExpr(); - _vm->_draw->_spriteBottom = _vm->_parse->parseValExpr(); - - _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); - _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); - - _vm->_draw->_transparency = load16(); - _vm->_draw->spriteOperation(DRAW_BLITSURF); - return false; -} - -bool Inter_v1::o1_putPixel(char &cmdCount, int16 &counter, int16 &retFlag) { - _vm->_draw->_destSurface = load16(); - - _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); - _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); - _vm->_draw->_frontColor = _vm->_parse->parseValExpr(); - _vm->_draw->spriteOperation(DRAW_PUTPIXEL); - return false; -} - -bool Inter_v1::o1_fillRect(char &cmdCount, int16 &counter, int16 &retFlag) { - _vm->_draw->_destSurface = load16(); - - _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); - _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); - _vm->_draw->_spriteRight = _vm->_parse->parseValExpr(); - _vm->_draw->_spriteBottom = _vm->_parse->parseValExpr(); - - _vm->_draw->_backColor = _vm->_parse->parseValExpr(); - _vm->_draw->spriteOperation(DRAW_FILLRECT); - return false; -} - -bool Inter_v1::o1_drawLine(char &cmdCount, int16 &counter, int16 &retFlag) { - _vm->_draw->_destSurface = load16(); - - _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); - _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); - _vm->_draw->_spriteRight = _vm->_parse->parseValExpr(); - _vm->_draw->_spriteBottom = _vm->_parse->parseValExpr(); - - _vm->_draw->_frontColor = _vm->_parse->parseValExpr(); - _vm->_draw->spriteOperation(DRAW_DRAWLINE); - return false; -} - -bool Inter_v1::o1_createSprite(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 index; - int16 height; - int16 width; - int16 flag; - - index = load16(); - width = load16(); - height = load16(); - - flag = load16(); - if (flag == 1) -// _vm->_draw->_spritesArray[index] = _vm->_video->initSurfDesc(_vm->_global->_videoMode, width, height, 2); - _vm->_draw->initSpriteSurf(index, _vm->_global->_videoMode, width, height, 2); - else -// _vm->_draw->_spritesArray[index] = _vm->_video->initSurfDesc(_vm->_global->_videoMode, width, height, 0); - _vm->_draw->initSpriteSurf(index, _vm->_global->_videoMode, width, height, 0); - - _vm->_video->clearSurf(_vm->_draw->_spritesArray[index]); - return false; -} - -bool Inter_v1::o1_freeSprite(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 index; - - index = load16(); - if (_vm->_draw->_spritesArray[index] == 0) - return false; - - _vm->_video->freeSurfDesc(_vm->_draw->_spritesArray[index]); - _vm->_draw->_spritesArray[index] = 0; - return false; -} - -bool Inter_v1::o1_playComposition(char &cmdCount, int16 &counter, int16 &retFlag) { - static int16 composition[50]; - int16 i; - int16 dataVar; - int16 freqVal; - - dataVar = _vm->_parse->parseVarIndex(); - freqVal = _vm->_parse->parseValExpr(); - for (i = 0; i < 50; i++) - composition[i] = (int16)VAR_OFFSET(dataVar + i * 4); - - _vm->_snd->playComposition(composition, freqVal); - return false; -} - -bool Inter_v1::o1_stopSound(char &cmdCount, int16 &counter, int16 &retFlag) { - if (_vm->_adlib) - _vm->_adlib->stopPlay(); - _vm->_snd->stopSound(_vm->_parse->parseValExpr()); - _soundEndTimeKey = 0; - return false; -} - -bool Inter_v1::o1_playSound(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 frequency; - int16 freq2; - int16 repCount; - int16 index; - - index = _vm->_parse->parseValExpr(); - repCount = _vm->_parse->parseValExpr(); - frequency = _vm->_parse->parseValExpr(); - - _vm->_snd->stopSound(0); - _soundEndTimeKey = 0; - if (_vm->_game->_soundSamples[index] == 0) - return false; - - if (repCount < 0) { - if (_vm->_global->_soundFlags < 2) - return false; - - repCount = -repCount; - _soundEndTimeKey = _vm->_util->getTimeKey(); - - if (frequency == 0) { - freq2 = _vm->_game->_soundSamples[index]->frequency; - } else { - freq2 = frequency; - } - _soundStopVal = - (10 * (_vm->_game->_soundSamples[index]->size / 2)) / freq2; - _soundEndTimeKey += - ((_vm->_game->_soundSamples[index]->size * repCount - - _vm->_game->_soundSamples[index]->size / 2) * 1000) / freq2; - } - _vm->_snd->playSample(_vm->_game->_soundSamples[index], repCount, frequency); - return false; -} - -bool Inter_v1::o1_loadCursor(char &cmdCount, int16 &counter, int16 &retFlag) { - Game::TotResItem *itemPtr; - int16 width; - int16 height; - int32 offset; - char *dataBuf; - int16 id; - int8 index; - - id = load16(); - index = *_vm->_global->_inter_execPtr++; - itemPtr = &_vm->_game->_totResourceTable->items[id]; - offset = itemPtr->offset; - - if (offset >= 0) { - dataBuf = - _vm->_game->_totResourceTable->dataPtr + szGame_TotResTable + - szGame_TotResItem * _vm->_game->_totResourceTable->itemsCount + offset; - } else { - dataBuf = _vm->_game->_imFileData + (int32)READ_LE_UINT32(&((int32 *)_vm->_game->_imFileData)[-offset - 1]); - } - - width = itemPtr->width; - height = itemPtr->height; - - _vm->_video->fillRect(_vm->_draw->_cursorSprites, index * _vm->_draw->_cursorWidth, 0, - index * _vm->_draw->_cursorWidth + _vm->_draw->_cursorWidth - 1, - _vm->_draw->_cursorHeight - 1, 0); - - _vm->_video->drawPackedSprite((byte*)dataBuf, width, height, - index * _vm->_draw->_cursorWidth, 0, 0, _vm->_draw->_cursorSprites); - _vm->_draw->_cursorAnimLow[index] = 0; - - return false; -} - -bool Inter_v1::o1_loadSpriteToPos(char &cmdCount, int16 &counter, int16 &retFlag) { - _vm->_draw->_spriteLeft = load16(); - - _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); - _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); - - _vm->_draw->_transparency = _vm->_global->_inter_execPtr[0]; - _vm->_draw->_destSurface = (_vm->_global->_inter_execPtr[0] / 2) - 1; - - if (_vm->_draw->_destSurface < 0) - _vm->_draw->_destSurface = 101; - _vm->_draw->_transparency &= 1; - _vm->_global->_inter_execPtr += 2; - - _vm->_draw->spriteOperation(DRAW_LOADSPRITE); - - return false; -} - -bool Inter_v1::o1_loadTot(char &cmdCount, int16 &counter, int16 &retFlag) { - char buf[20]; - int8 size; - int16 i; - - if ((*_vm->_global->_inter_execPtr & 0x80) != 0) { - _vm->_global->_inter_execPtr++; - evalExpr(0); - strcpy(buf, _vm->_global->_inter_resStr); - } else { - size = *_vm->_global->_inter_execPtr++; - for (i = 0; i < size; i++) - buf[i] = *_vm->_global->_inter_execPtr++; - - buf[size] = 0; - } - - strcat(buf, ".tot"); - _terminate = true; - strcpy(_vm->_game->_totToLoad, buf); - - return false; -} - -bool Inter_v1::o1_keyFunc(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 flag; - int16 key; - uint32 now; - static uint32 lastCalled = 0; - - flag = load16(); - animPalette(); - _vm->_draw->blitInvalidated(); - - now = _vm->_util->getTimeKey(); - if (!_noBusyWait) - if ((now - lastCalled) <= 20) - _vm->_util->longDelay(1); - lastCalled = now; - _noBusyWait = false; - - if (flag != 0) { - - if (flag != 1) { - if (flag != 2) { - _vm->_snd->speakerOnUpdate(flag); - if (flag < 20) { - _vm->_util->delay(flag); - _noBusyWait = true; - } - else - _vm->_util->longDelay(flag); - return false; - } - - key = 0; - - if (_vm->_global->_pressedKeys[0x48]) - key |= 1; - - if (_vm->_global->_pressedKeys[0x50]) - key |= 2; - - if (_vm->_global->_pressedKeys[0x4d]) - key |= 4; - - if (_vm->_global->_pressedKeys[0x4b]) - key |= 8; - - if (_vm->_global->_pressedKeys[0x1c]) - key |= 0x10; - - if (_vm->_global->_pressedKeys[0x39]) - key |= 0x20; - - if (_vm->_global->_pressedKeys[1]) - key |= 0x40; - - if (_vm->_global->_pressedKeys[0x1d]) - key |= 0x80; - - if (_vm->_global->_pressedKeys[0x2a]) - key |= 0x100; - - if (_vm->_global->_pressedKeys[0x36]) - key |= 0x200; - - if (_vm->_global->_pressedKeys[0x38]) - key |= 0x400; - - if (_vm->_global->_pressedKeys[0x3b]) - key |= 0x800; - - if (_vm->_global->_pressedKeys[0x3c]) - key |= 0x1000; - - if (_vm->_global->_pressedKeys[0x3d]) - key |= 0x2000; - - if (_vm->_global->_pressedKeys[0x3e]) - key |= 0x4000; - - WRITE_VAR(0, key); - _vm->_util->waitKey(); - return false; - } - key = _vm->_game->checkKeys(&_vm->_global->_inter_mouseX, &_vm->_global->_inter_mouseY, &_vm->_game->_mouseButtons, 0); - - storeKey(key); - return false; - } else { - _vm->_draw->_showCursor &= ~2; - _vm->_util->longDelay(1); - key = _vm->_game->checkCollisions(0, 0, 0, 0); - storeKey(key); - - if (flag == 1) - return false; - - _vm->_util->waitKey(); - } - return false; -} - -bool Inter_v1::o1_repeatUntil(char &cmdCount, int16 &counter, int16 &retFlag) { - char *blockPtr; - int16 size; - char flag; - - _nestLevel[0]++; - blockPtr = _vm->_global->_inter_execPtr; - - do { - _vm->_global->_inter_execPtr = blockPtr; - size = READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; - - funcBlock(1); - _vm->_global->_inter_execPtr = blockPtr + size + 1; - flag = evalBoolResult(); - } while (flag == 0 && !_breakFlag && !_terminate && !_vm->_quitRequested); - - _nestLevel[0]--; - - if (*_breakFromLevel > -1) { - _breakFlag = false; - *_breakFromLevel = -1; - } - return false; -} - -bool Inter_v1::o1_whileDo(char &cmdCount, int16 &counter, int16 &retFlag) { - char *blockPtr; - char *savedIP; - char flag; - int16 size; - - _nestLevel[0]++; - do { - savedIP = _vm->_global->_inter_execPtr; - flag = evalBoolResult(); - - if (_terminate) - return false; - - blockPtr = _vm->_global->_inter_execPtr; - - size = READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; - - if (flag != 0) { - funcBlock(1); - _vm->_global->_inter_execPtr = savedIP; - } else { - _vm->_global->_inter_execPtr += size; - } - - if (_breakFlag || _terminate || _vm->_quitRequested) { - _vm->_global->_inter_execPtr = blockPtr; - _vm->_global->_inter_execPtr += size; - break; - } - } while (flag != 0); - - _nestLevel[0]--; - if (*_breakFromLevel > -1) { - _breakFlag = false; - *_breakFromLevel = -1; - } - return false; -} - -void Inter_v1::o1_setRenderFlags(void) { +void Inter_v1::o1_setRenderFlags() { _vm->_draw->_renderFlags = _vm->_parse->parseValExpr(); } -void Inter_v1::o1_loadAnim(void) { +void Inter_v1::o1_loadAnim() { _vm->_scenery->loadAnim(0); } -void Inter_v1::o1_freeAnim(void) { +void Inter_v1::o1_freeAnim() { _vm->_scenery->freeAnim(-1); } -void Inter_v1::o1_updateAnim(void) { +void Inter_v1::o1_updateAnim() { int16 deltaX; int16 deltaY; int16 flags; @@ -1646,43 +888,59 @@ void Inter_v1::o1_updateAnim(void) { evalExpr(&layer); evalExpr(&frame); flags = load16(); - _vm->_scenery->updateAnim(layer, frame, animation, flags, deltaX, deltaY, 1); + _vm->_scenery->updateAnim(layer, frame, animation, flags, + deltaX, deltaY, 1); } -void Inter_v1::o1_initMult(void) { +void Inter_v1::o1_initMult() { int16 oldAnimHeight; int16 oldAnimWidth; int16 oldObjCount; - int16 i; int16 posXVar; int16 posYVar; int16 animDataVar; - oldAnimWidth = _vm->_anim->_areaWidth; - oldAnimHeight = _vm->_anim->_areaHeight; + oldAnimWidth = _vm->_mult->_animWidth; + oldAnimHeight = _vm->_mult->_animHeight; oldObjCount = _vm->_mult->_objCount; - _vm->_anim->_areaLeft = load16(); - _vm->_anim->_areaTop = load16(); - _vm->_anim->_areaWidth = load16(); - _vm->_anim->_areaHeight = load16(); + _vm->_mult->_animLeft = load16(); + _vm->_mult->_animTop = load16(); + _vm->_mult->_animWidth = load16(); + _vm->_mult->_animHeight = load16(); _vm->_mult->_objCount = load16(); posXVar = _vm->_parse->parseVarIndex(); posYVar = _vm->_parse->parseVarIndex(); animDataVar = _vm->_parse->parseVarIndex(); + if (_vm->_mult->_objects && (oldObjCount != _vm->_mult->_objCount)) { + warning("Initializing new objects without having " + "cleaned up the old ones at first"); + delete[] _vm->_mult->_objects; + delete[] _vm->_mult->_renderData; + _vm->_mult->_objects = 0; + _vm->_mult->_renderObjs = 0; + } + if (_vm->_mult->_objects == 0) { _vm->_mult->_renderData = new int16[_vm->_mult->_objCount * 9]; - memset(_vm->_mult->_renderData, 0, _vm->_mult->_objCount * 9 * sizeof(int16)); + memset(_vm->_mult->_renderData, 0, + _vm->_mult->_objCount * 9 * sizeof(int16)); _vm->_mult->_objects = new Mult::Mult_Object[_vm->_mult->_objCount]; - memset(_vm->_mult->_objects, 0, _vm->_mult->_objCount * sizeof(Mult::Mult_Object)); + memset(_vm->_mult->_objects, 0, + _vm->_mult->_objCount * sizeof(Mult::Mult_Object)); + + for (int i = 0; i < _vm->_mult->_objCount; i++) { + _vm->_mult->_objects[i].pPosX = + (int32 *)(_vm->_global->_inter_variables + + i * 4 + (posXVar / 4) * 4); + _vm->_mult->_objects[i].pPosY = + (int32 *)(_vm->_global->_inter_variables + + i * 4 + (posYVar / 4) * 4); - for (i = 0; i < _vm->_mult->_objCount; i++) { - _vm->_mult->_objects[i].pPosX = (int32 *)(_vm->_global->_inter_variables + i * 4 + (posXVar / 4) * 4); - _vm->_mult->_objects[i].pPosY = (int32 *)(_vm->_global->_inter_variables + i * 4 + (posYVar / 4) * 4); _vm->_mult->_objects[i].pAnimData = - (Mult::Mult_AnimData *) (_vm->_global->_inter_variables + animDataVar + - i * 4 * _vm->_global->_inter_animDataSize); + (Mult::Mult_AnimData *) (_vm->_global->_inter_variables + + animDataVar + i * 4 * _vm->_global->_inter_animDataSize); _vm->_mult->_objects[i].pAnimData->isStatic = 1; _vm->_mult->_objects[i].tick = 0; @@ -1691,77 +949,112 @@ void Inter_v1::o1_initMult(void) { _vm->_mult->_objects[i].lastTop = -1; _vm->_mult->_objects[i].lastBottom = -1; } - } else if (oldObjCount != _vm->_mult->_objCount) { - error("o1_initMult: Object count changed, but storage didn't (old count = %d, new count = %d)", - oldObjCount, _vm->_mult->_objCount); } - if (_vm->_anim->_animSurf != 0 && - (oldAnimWidth != _vm->_anim->_areaWidth - || oldAnimHeight != _vm->_anim->_areaHeight)) { - _vm->_video->freeSurfDesc(_vm->_anim->_animSurf); - _vm->_anim->_animSurf = 0; - _vm->_draw->_spritesArray[22] = 0; + if (_vm->_mult->_animSurf && + ((oldAnimWidth != _vm->_mult->_animWidth) || + (oldAnimHeight != _vm->_mult->_animHeight))) { + _vm->_draw->freeSprite(22); + _vm->_mult->_animSurf = 0; } - if (_vm->_anim->_animSurf == 0) { - _vm->_anim->_animSurf = _vm->_video->initSurfDesc(_vm->_global->_videoMode, - _vm->_anim->_areaWidth, _vm->_anim->_areaHeight, 0); - _vm->_draw->_spritesArray[22] = _vm->_anim->_animSurf; + if (!_vm->_mult->_animSurf) { + _vm->_draw->initSpriteSurf(22, _vm->_mult->_animWidth, + _vm->_mult->_animHeight, 0); + _vm->_mult->_animSurf = _vm->_draw->_spritesArray[22]; } - _vm->_video->drawSprite(_vm->_draw->_backSurface, _vm->_anim->_animSurf, - _vm->_anim->_areaLeft, _vm->_anim->_areaTop, - _vm->_anim->_areaLeft + _vm->_anim->_areaWidth - 1, - _vm->_anim->_areaTop + _vm->_anim->_areaHeight - 1, 0, 0, 0); + _vm->_video->drawSprite(_vm->_draw->_backSurface, _vm->_mult->_animSurf, + _vm->_mult->_animLeft, _vm->_mult->_animTop, + _vm->_mult->_animLeft + _vm->_mult->_animWidth - 1, + _vm->_mult->_animTop + _vm->_mult->_animHeight - 1, 0, 0, 0); debugC(4, kDebugGraphics, "o1_initMult: x = %d, y = %d, w = %d, h = %d", - _vm->_anim->_areaLeft, _vm->_anim->_areaTop, _vm->_anim->_areaWidth, _vm->_anim->_areaHeight); - debugC(4, kDebugGraphics, " _vm->_mult->_objCount = %d, animation data size = %d", _vm->_mult->_objCount, _vm->_global->_inter_animDataSize); + _vm->_mult->_animLeft, _vm->_mult->_animTop, + _vm->_mult->_animWidth, _vm->_mult->_animHeight); + debugC(4, kDebugGraphics, " _vm->_mult->_objCount = %d, " + "animation data size = %d", _vm->_mult->_objCount, + _vm->_global->_inter_animDataSize); } -void Inter_v1::o1_multFreeMult(void) { +void Inter_v1::o1_freeMult() { _vm->_mult->freeMult(); } -void Inter_v1::o1_animate(void) { +void Inter_v1::o1_animate() { _vm->_mult->animate(); } -void Inter_v1::o1_multLoadMult(void) { - loadMult(); +void Inter_v1::o1_loadMultObject() { + int16 val; + int16 objIndex; + char *multData; + + evalExpr(&objIndex); + evalExpr(&val); + *_vm->_mult->_objects[objIndex].pPosX = val; + evalExpr(&val); + *_vm->_mult->_objects[objIndex].pPosY = val; + + debugC(4, kDebugGameFlow, "Loading mult object %d", objIndex); + + multData = (char *) _vm->_mult->_objects[objIndex].pAnimData; + for (int i = 0; i < 11; i++) { + if (READ_LE_UINT16(_vm->_global->_inter_execPtr) != 99) { + evalExpr(&val); + multData[i] = val; + } else + _vm->_global->_inter_execPtr++; + } } -void Inter_v1::o1_storeParams(void) { - _vm->_scenery->interStoreParams(); +void Inter_v1::o1_getAnimLayerInfo() { + int16 anim; + int16 layer; + int16 varDX, varDY; + int16 varUnk0; + int16 varFrames; + + evalExpr(&anim); + evalExpr(&layer); + + varDX = _vm->_parse->parseVarIndex(); + varDY = _vm->_parse->parseVarIndex(); + varUnk0 = _vm->_parse->parseVarIndex(); + varFrames = _vm->_parse->parseVarIndex(); + + _vm->_scenery->writeAnimLayerInfo(anim, layer, + varDX, varDY, varUnk0, varFrames); } -void Inter_v1::o1_getObjAnimSize(void) { - Mult::Mult_AnimData *pAnimData; +void Inter_v1::o1_getObjAnimSize() { int16 objIndex; evalExpr(&objIndex); - pAnimData = _vm->_mult->_objects[objIndex].pAnimData; - if (pAnimData->isStatic == 0) { - _vm->_scenery->updateAnim(pAnimData->layer, pAnimData->frame, - pAnimData->animation, 0, *(_vm->_mult->_objects[objIndex].pPosX), + + Mult::Mult_AnimData &animData = *(_vm->_mult->_objects[objIndex].pAnimData); + if (animData.isStatic == 0) + _vm->_scenery->updateAnim(animData.layer, animData.frame, + animData.animation, 0, *(_vm->_mult->_objects[objIndex].pPosX), *(_vm->_mult->_objects[objIndex].pPosY), 0); - } + + _vm->_scenery->_toRedrawLeft = MAX(_vm->_scenery->_toRedrawLeft, (int16) 0); + _vm->_scenery->_toRedrawTop = MAX(_vm->_scenery->_toRedrawTop, (int16) 0); WRITE_VAR_OFFSET(_vm->_parse->parseVarIndex(), _vm->_scenery->_toRedrawLeft); WRITE_VAR_OFFSET(_vm->_parse->parseVarIndex(), _vm->_scenery->_toRedrawTop); WRITE_VAR_OFFSET(_vm->_parse->parseVarIndex(), _vm->_scenery->_toRedrawRight); WRITE_VAR_OFFSET(_vm->_parse->parseVarIndex(), _vm->_scenery->_toRedrawBottom); } -void Inter_v1::o1_loadStatic(void) { +void Inter_v1::o1_loadStatic() { _vm->_scenery->loadStatic(0); } -void Inter_v1::o1_freeStatic(void) { +void Inter_v1::o1_freeStatic() { _vm->_scenery->freeStatic(-1); } -void Inter_v1::o1_renderStatic(void) { +void Inter_v1::o1_renderStatic() { int16 layer; int16 index; @@ -1770,12 +1063,12 @@ void Inter_v1::o1_renderStatic(void) { _vm->_scenery->renderStatic(index, layer); } -void Inter_v1::o1_loadCurLayer(void) { +void Inter_v1::o1_loadCurLayer() { evalExpr(&_vm->_scenery->_curStatic); evalExpr(&_vm->_scenery->_curStaticLayer); } -void Inter_v1::o1_playCDTrack(void) { +void Inter_v1::o1_playCDTrack() { evalExpr(0); if (_vm->_platform == Common::kPlatformMacintosh) { if (_vm->_adlib) @@ -1785,7 +1078,7 @@ void Inter_v1::o1_playCDTrack(void) { _vm->_cdrom->startTrack(_vm->_global->_inter_resStr); } -void Inter_v1::o1_getCDTrackPos(void) { +void Inter_v1::o1_getCDTrackPos() { // Used in gob1 CD // Some scripts busy-wait while calling this opcode. @@ -1800,7 +1093,7 @@ void Inter_v1::o1_getCDTrackPos(void) { WRITE_VAR(5, pos); } -void Inter_v1::o1_stopCD(void) { +void Inter_v1::o1_stopCD() { if (_vm->_platform == Common::kPlatformMacintosh) { if (_vm->_adlib) _vm->_adlib->stopPlay(); @@ -1809,7 +1102,7 @@ void Inter_v1::o1_stopCD(void) { _vm->_cdrom->stopPlaying(); } -void Inter_v1::o1_loadFontToSprite(void) { +void Inter_v1::o1_loadFontToSprite() { int16 i = load16(); _vm->_draw->_fontToSprite[i].sprite = load16(); _vm->_draw->_fontToSprite[i].base = load16(); @@ -1817,7 +1110,7 @@ void Inter_v1::o1_loadFontToSprite(void) { _vm->_draw->_fontToSprite[i].height = load16(); } -void Inter_v1::o1_freeFontToSprite(void) { +void Inter_v1::o1_freeFontToSprite() { int16 i = load16(); _vm->_draw->_fontToSprite[i].sprite = -1; _vm->_draw->_fontToSprite[i].base = -1; @@ -1825,14 +1118,15 @@ void Inter_v1::o1_freeFontToSprite(void) { _vm->_draw->_fontToSprite[i].height = -1; } -bool Inter_v1::o1_callSub(char &cmdCount, int16 &counter, int16 &retFlag) { +bool Inter_v1::o1_callSub(OpFuncParams ¶ms) { char *storedIP; uint32 offset; storedIP = _vm->_global->_inter_execPtr; offset = READ_LE_UINT16(_vm->_global->_inter_execPtr); - debugC(5, kDebugGameFlow, "tot = \"%s\", offset = %d", _vm->_game->_curTotFile, offset); + debugC(5, kDebugGameFlow, "tot = \"%s\", offset = %d", + _vm->_game->_curTotFile, offset); // Skipping the copy protection screen in Gobliiins if (!_vm->_copyProtection && (_vm->_features & GF_GOB1) && (offset == 3905) @@ -1849,9 +1143,9 @@ bool Inter_v1::o1_callSub(char &cmdCount, int16 &counter, int16 &retFlag) { return false; } - _vm->_global->_inter_execPtr = (char *)_vm->_game->_totFileData + offset; + _vm->_global->_inter_execPtr = (char *) _vm->_game->_totFileData + offset; - if (counter == cmdCount && retFlag == 2) + if ((params.counter == params.cmdCount) && (params.retFlag == 2)) return true; callSub(2); @@ -1860,19 +1154,56 @@ bool Inter_v1::o1_callSub(char &cmdCount, int16 &counter, int16 &retFlag) { return false; } -bool Inter_v1::o1_drawPrintText(char &cmdCount, int16 &counter, int16 &retFlag) { - _vm->_draw->printText(); +bool Inter_v1::o1_printTotText(OpFuncParams ¶ms) { + _vm->_draw->printTotText(load16()); + return false; +} + +bool Inter_v1::o1_loadCursor(OpFuncParams ¶ms) { + Game::TotResItem *itemPtr; + int16 width, height; + char *dataBuf; + int32 offset; + int16 id; + int8 index; + + id = load16(); + index = *_vm->_global->_inter_execPtr++; + itemPtr = &_vm->_game->_totResourceTable->items[id]; + offset = itemPtr->offset; + + if (offset < 0) { + offset = (-offset - 1) * 4; + dataBuf = _vm->_game->_imFileData + + (int32) READ_LE_UINT32(_vm->_game->_imFileData + offset); + } else + dataBuf = _vm->_game->_totResourceTable->dataPtr + szGame_TotResTable + + szGame_TotResItem * _vm->_game->_totResourceTable->itemsCount + + offset; + + width = itemPtr->width; + height = itemPtr->height; + + _vm->_video->fillRect(_vm->_draw->_cursorSprites, + index * _vm->_draw->_cursorWidth, 0, + index * _vm->_draw->_cursorWidth + _vm->_draw->_cursorWidth - 1, + _vm->_draw->_cursorHeight - 1, 0); + + _vm->_video->drawPackedSprite((byte*) dataBuf, width, height, + index * _vm->_draw->_cursorWidth, 0, 0, _vm->_draw->_cursorSprites); + _vm->_draw->_cursorAnimLow[index] = 0; + return false; } -bool Inter_v1::o1_call(char &cmdCount, int16 &counter, int16 &retFlag) { +bool Inter_v1::o1_switch(OpFuncParams ¶ms) { char *callAddr; checkSwitchTable(&callAddr); char *storedIP = _vm->_global->_inter_execPtr; _vm->_global->_inter_execPtr = callAddr; - if (counter == cmdCount && retFlag == 2) + if ((params.counter == params.cmdCount) && (params.retFlag == 2)) return true; funcBlock(0); @@ -1881,210 +1212,669 @@ bool Inter_v1::o1_call(char &cmdCount, int16 &counter, int16 &retFlag) { return false; } -bool Inter_v1::o1_callBool(char &cmdCount, int16 &counter, int16 &retFlag) { - byte cmd; - bool boolRes = evalBoolResult() != 0; +bool Inter_v1::o1_repeatUntil(OpFuncParams ¶ms) { + char *blockPtr; + int16 size; + bool flag; + + _nestLevel[0]++; + blockPtr = _vm->_global->_inter_execPtr; + + do { + _vm->_global->_inter_execPtr = blockPtr; + size = READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + + funcBlock(1); + _vm->_global->_inter_execPtr = blockPtr + size + 1; + flag = evalBoolResult(); + } while (!flag && !_break && !_terminate && !_vm->_quitRequested); + + _nestLevel[0]--; + + if (*_breakFromLevel > -1) { + _break = false; + *_breakFromLevel = -1; + } + return false; +} + +bool Inter_v1::o1_whileDo(OpFuncParams ¶ms) { + char *blockPtr; + char *savedIP; + bool flag; + int16 size; + + _nestLevel[0]++; + do { + savedIP = _vm->_global->_inter_execPtr; + flag = evalBoolResult(); + + if (_terminate) + return false; + + blockPtr = _vm->_global->_inter_execPtr; + + size = READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + + if (flag) { + funcBlock(1); + _vm->_global->_inter_execPtr = savedIP; + } else + _vm->_global->_inter_execPtr += size; + + if (_break || _terminate || _vm->_quitRequested) { + _vm->_global->_inter_execPtr = blockPtr; + _vm->_global->_inter_execPtr += size; + break; + } + } while (flag); - if (boolRes != 0) { - if (counter == cmdCount - && retFlag == 2) + _nestLevel[0]--; + if (*_breakFromLevel > -1) { + _break = false; + *_breakFromLevel = -1; + } + return false; +} + +bool Inter_v1::o1_if(OpFuncParams ¶ms) { + byte cmd; + bool boolRes; + + boolRes = evalBoolResult(); + if (boolRes) { + if ((params.counter == params.cmdCount) && (params.retFlag == 2)) return true; char *storedIP = _vm->_global->_inter_execPtr; funcBlock(0); _vm->_global->_inter_execPtr = storedIP; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; - debugC(5, kDebugGameFlow, "cmd = %d", (int16)*_vm->_global->_inter_execPtr); - cmd = (byte)(*_vm->_global->_inter_execPtr) >> 4; + debugC(5, kDebugGameFlow, "cmd = %d", + (int16) *_vm->_global->_inter_execPtr); + + cmd = (byte) (*_vm->_global->_inter_execPtr) >> 4; _vm->_global->_inter_execPtr++; if (cmd != 12) return false; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; } else { - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + + debugC(5, kDebugGameFlow, "cmd = %d", + (int16) *_vm->_global->_inter_execPtr); - debugC(5, kDebugGameFlow, "cmd = %d", (int16)*_vm->_global->_inter_execPtr); - cmd = (byte)(*_vm->_global->_inter_execPtr) >> 4; + cmd = (byte) (*_vm->_global->_inter_execPtr) >> 4; _vm->_global->_inter_execPtr++; if (cmd != 12) return false; - if (counter == cmdCount && retFlag == 2) + if ((params.counter == params.cmdCount) && (params.retFlag == 2)) return true; char *storedIP = _vm->_global->_inter_execPtr; funcBlock(0); _vm->_global->_inter_execPtr = storedIP; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; } return false; } -bool Inter_v1::o1_palLoad(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 i; - int16 ind1; - int16 ind2; - byte cmd; +bool Inter_v1::o1_evaluateStore(OpFuncParams ¶ms) { + char *savedPos; + int16 token; + int16 result; + int16 varOff; + + savedPos = _vm->_global->_inter_execPtr; + varOff = _vm->_parse->parseVarIndex(); + token = evalExpr(&result); + switch (savedPos[0]) { + case 23: + case 26: + WRITE_VAR_OFFSET(varOff, _vm->_global->_inter_resVal); + break; + + case 25: + case 28: + if (token == 20) + WRITE_VARO_UINT8(varOff, result); + else + WRITE_VARO_STR(varOff, _vm->_global->_inter_resStr); + break; + + } + return false; +} + +bool Inter_v1::o1_loadSpriteToPos(OpFuncParams ¶ms) { + _vm->_draw->_spriteLeft = load16(); + + _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); + _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); + + _vm->_draw->_transparency = *_vm->_global->_inter_execPtr & 1; + _vm->_draw->_destSurface = (*_vm->_global->_inter_execPtr >> 1) - 1; + if (_vm->_draw->_destSurface < 0) + _vm->_draw->_destSurface = 101; + + _vm->_global->_inter_execPtr += 2; + + _vm->_draw->spriteOperation(DRAW_LOADSPRITE); + + return false; +} + +bool Inter_v1::o1_printText(OpFuncParams ¶ms) { + char buf[60]; + int i; + + _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); + _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); + + _vm->_draw->_backColor = _vm->_parse->parseValExpr(); + _vm->_draw->_frontColor = _vm->_parse->parseValExpr(); + _vm->_draw->_fontIndex = _vm->_parse->parseValExpr(); + _vm->_draw->_destSurface = 21; + _vm->_draw->_textToPrint = buf; + _vm->_draw->_transparency = 0; + + if (_vm->_draw->_backColor >= 16) { + _vm->_draw->_backColor = 0; + _vm->_draw->_transparency = 1; + } + + do { + for (i = 0; (*_vm->_global->_inter_execPtr != '.') && + ((byte) *_vm->_global->_inter_execPtr != 200); + i++, _vm->_global->_inter_execPtr++) { + buf[i] = *_vm->_global->_inter_execPtr; + } + + if ((byte) *_vm->_global->_inter_execPtr != 200) { + _vm->_global->_inter_execPtr++; + switch (*_vm->_global->_inter_execPtr) { + case 23: + case 26: + sprintf(buf + i, "%d", + VAR_OFFSET(_vm->_parse->parseVarIndex())); + break; + + case 25: + case 28: + sprintf(buf + i, "%s", + GET_VARO_STR(_vm->_parse->parseVarIndex())); + break; + } + _vm->_global->_inter_execPtr++; + } else + buf[i] = 0; + + _vm->_draw->spriteOperation(DRAW_PRINTTEXT); + } while ((byte) *_vm->_global->_inter_execPtr != 200); + + _vm->_global->_inter_execPtr++; + + return false; +} + +bool Inter_v1::o1_loadTot(OpFuncParams ¶ms) { + char buf[20]; + int8 size; + + if ((*_vm->_global->_inter_execPtr & 0x80) != 0) { + _vm->_global->_inter_execPtr++; + evalExpr(0); + strcpy(buf, _vm->_global->_inter_resStr); + } else { + size = *_vm->_global->_inter_execPtr++; + for (int i = 0; i < size; i++) + buf[i] = *_vm->_global->_inter_execPtr++; + + buf[size] = 0; + } + + strcat(buf, ".tot"); + if (_terminate != 2) + _terminate = 1; + strcpy(_vm->_game->_totToLoad, buf); + + return false; +} + +bool Inter_v1::o1_palLoad(OpFuncParams ¶ms) { + int index1, index2; char *palPtr; + byte cmd; cmd = *_vm->_global->_inter_execPtr++; - _vm->_draw->_applyPal = 0; - if (cmd & 0x80) - cmd &= 0x7f; - else - _vm->_draw->_applyPal = 1; + switch (cmd & 0x7F) { + case 48: + if ((_vm->_global->_fakeVideoMode < 0x32) || + (_vm->_global->_fakeVideoMode > 0x63)) { + _vm->_global->_inter_execPtr += 48; + return false; + } + break; + + case 49: + if ((_vm->_global->_fakeVideoMode != 5) && + (_vm->_global->_fakeVideoMode != 7)) { + _vm->_global->_inter_execPtr += 18; + return false; + } + break; + + case 50: + if (_vm->_global->_colorCount == 256) { + _vm->_global->_inter_execPtr += 16; + return false; + } + break; + + case 51: + if (_vm->_global->_fakeVideoMode < 0x64) { + _vm->_global->_inter_execPtr += 2; + return false; + } + break; + + case 52: + if (_vm->_global->_colorCount == 256) { + _vm->_global->_inter_execPtr += 48; + return false; + } + break; + + case 53: + if (_vm->_global->_colorCount != 256) { + _vm->_global->_inter_execPtr += 2; + return false; + } + break; + + case 54: + if (_vm->_global->_fakeVideoMode < 0x13) { + return false; + } + break; + + case 61: + if (_vm->_global->_fakeVideoMode < 0x13) { + *_vm->_global->_inter_execPtr += 4; + return false; + } + break; + } + + if ((cmd & 0x7F) == 0x30) { + _vm->_global->_inter_execPtr += 48; + return false; + } + + _vm->_draw->_applyPal = !(cmd & 0x80); + cmd &= 0x7F; if (cmd == 49) { - warning("o1_palLoad: cmd == 49 is not supported"); - //var_B = 1; - for (i = 0; i < 18; i++, _vm->_global->_inter_execPtr++) { + bool allZero = true; + + for (int i = 2; i < 18; i++) { + if (_vm->_global->_inter_execPtr[i] != 0) { + allZero = false; + break; + } + } + if (!allZero) { + _vm->_video->clearSurf(_vm->_draw->_frontSurface); + _vm->_draw->_noInvalidated57 = true; + _vm->_global->_inter_execPtr += 18; + return false; + } + _vm->_draw->_noInvalidated57 = false; + + for (int i = 0; i < 18; i++, _vm->_global->_inter_execPtr++) { if (i < 2) { - if (_vm->_draw->_applyPal == 0) + if (!_vm->_draw->_applyPal) continue; _vm->_draw->_unusedPalette1[i] = *_vm->_global->_inter_execPtr; continue; } - //if (*inter_execPtr != 0) - // var_B = 0; - ind1 = *_vm->_global->_inter_execPtr >> 4; - ind2 = (*_vm->_global->_inter_execPtr & 0xf); + index1 = *_vm->_global->_inter_execPtr >> 4; + index2 = (*_vm->_global->_inter_execPtr & 0xF); _vm->_draw->_unusedPalette1[i] = - ((_vm->_draw->_palLoadData1[ind1] + _vm->_draw->_palLoadData2[ind2]) << 8) + - (_vm->_draw->_palLoadData2[ind1] + _vm->_draw->_palLoadData1[ind2]); + ((_vm->_draw->_palLoadData1[index1] + + _vm->_draw->_palLoadData2[index2]) << 8) + + (_vm->_draw->_palLoadData2[index1] + + _vm->_draw->_palLoadData1[index2]); } _vm->_global->_pPaletteDesc->unused1 = _vm->_draw->_unusedPalette1; + _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); + return false; } switch (cmd) { - case 52: - for (i = 0; i < 16; i++, _vm->_global->_inter_execPtr += 3) { - _vm->_draw->_vgaSmallPalette[i].red = _vm->_global->_inter_execPtr[0]; - _vm->_draw->_vgaSmallPalette[i].green = _vm->_global->_inter_execPtr[1]; - _vm->_draw->_vgaSmallPalette[i].blue = _vm->_global->_inter_execPtr[2]; - } - break; - case 50: - for (i = 0; i < 16; i++, _vm->_global->_inter_execPtr++) + for (int i = 0; i < 16; i++, _vm->_global->_inter_execPtr++) _vm->_draw->_unusedPalette2[i] = *_vm->_global->_inter_execPtr; break; + case 52: + for (int i = 0; i < 16; i++, _vm->_global->_inter_execPtr += 3) { + _vm->_draw->_vgaPalette[i].red = _vm->_global->_inter_execPtr[0]; + _vm->_draw->_vgaPalette[i].green = _vm->_global->_inter_execPtr[1]; + _vm->_draw->_vgaPalette[i].blue = _vm->_global->_inter_execPtr[2]; + } + break; + case 53: palPtr = _vm->_game->loadTotResource(_vm->_inter->load16()); - memcpy((char *)_vm->_draw->_vgaPalette, palPtr, 768); + memcpy((char *) _vm->_draw->_vgaPalette, palPtr, 768); break; case 54: - memset((char *)_vm->_draw->_vgaPalette, 0, 768); + memset((char *) _vm->_draw->_vgaPalette, 0, 768); + break; + + case 61: + index1 = *_vm->_global->_inter_execPtr++; + index2 = (*_vm->_global->_inter_execPtr++ - index1 + 1) * 3; + palPtr = _vm->_game->loadTotResource(_vm->_inter->load16()); + memcpy((char *) _vm->_draw->_vgaPalette + index1 * 3, + palPtr + index1 * 3, index2); + + if (_vm->_draw->_applyPal) { + _vm->_draw->_applyPal = false; + _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); + return false; + } break; } + if (!_vm->_draw->_applyPal) { _vm->_global->_pPaletteDesc->unused2 = _vm->_draw->_unusedPalette2; _vm->_global->_pPaletteDesc->unused1 = _vm->_draw->_unusedPalette1; - if (_vm->_global->_videoMode != 0x13) - _vm->_global->_pPaletteDesc->vgaPal = (Video::Color *)_vm->_draw->_vgaSmallPalette; - else - _vm->_global->_pPaletteDesc->vgaPal = (Video::Color *)_vm->_draw->_vgaPalette; + if (_vm->_global->_videoMode < 0x13) { + _vm->_global->_pPaletteDesc->vgaPal = _vm->_draw->_vgaSmallPalette; + _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, 0, 0); + return false; + } + if ((_vm->_global->_videoMode < 0x32) || + (_vm->_global->_videoMode >= 0x64)) { + _vm->_global->_pPaletteDesc->vgaPal = _vm->_draw->_vgaPalette; + _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, 0, 0); + return false; + } + _vm->_global->_pPaletteDesc->vgaPal = _vm->_draw->_vgaSmallPalette; + _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, 0, 0); + } + + return false; +} + +bool Inter_v1::o1_keyFunc(OpFuncParams ¶ms) { + static uint32 lastCalled = 0; + int16 cmd; + int16 key; + uint32 now; + + cmd = load16(); + animPalette(); + _vm->_draw->blitInvalidated(); + + now = _vm->_util->getTimeKey(); + if (!_noBusyWait) + if ((now - lastCalled) <= 20) + _vm->_util->longDelay(1); + lastCalled = now; + _noBusyWait = false; + + switch (cmd) { + case 0: + _vm->_draw->_showCursor &= ~2; + _vm->_util->longDelay(1); + key = _vm->_game->checkCollisions(0, 0, 0, 0); + storeKey(key); + + _vm->_util->clearKeyBuf(); + break; + + case 1: + key = _vm->_game->checkKeys(&_vm->_global->_inter_mouseX, + &_vm->_global->_inter_mouseY, &_vm->_game->_mouseButtons, 0); + storeKey(key); + break; + + case 2: + key = 0; + + if (_vm->_global->_pressedKeys[0x48]) + key |= 1; + + if (_vm->_global->_pressedKeys[0x50]) + key |= 2; - _vm->_palanim->fade((Video::PalDesc *) _vm->_global->_pPaletteDesc, 0, 0); + if (_vm->_global->_pressedKeys[0x4D]) + key |= 4; + + if (_vm->_global->_pressedKeys[0x4B]) + key |= 8; + + if (_vm->_global->_pressedKeys[0x1C]) + key |= 0x10; + + if (_vm->_global->_pressedKeys[0x39]) + key |= 0x20; + + if (_vm->_global->_pressedKeys[1]) + key |= 0x40; + + if (_vm->_global->_pressedKeys[0x1D]) + key |= 0x80; + + if (_vm->_global->_pressedKeys[0x2A]) + key |= 0x100; + + if (_vm->_global->_pressedKeys[0x36]) + key |= 0x200; + + if (_vm->_global->_pressedKeys[0x38]) + key |= 0x400; + + if (_vm->_global->_pressedKeys[0x3B]) + key |= 0x800; + + if (_vm->_global->_pressedKeys[0x3C]) + key |= 0x1000; + + if (_vm->_global->_pressedKeys[0x3D]) + key |= 0x2000; + + if (_vm->_global->_pressedKeys[0x3E]) + key |= 0x4000; + + WRITE_VAR(0, key); + _vm->_util->clearKeyBuf(); + break; + + default: + _vm->_snd->speakerOnUpdate(cmd); + if (cmd < 20) { + _vm->_util->delay(cmd); + _noBusyWait = true; + } else + _vm->_util->longDelay(cmd); + break; + } + + return false; +} + +bool Inter_v1::o1_capturePush(OpFuncParams ¶ms) { + int16 left, top; + int16 width, height; + + left = _vm->_parse->parseValExpr(); + top = _vm->_parse->parseValExpr(); + width = _vm->_parse->parseValExpr(); + height = _vm->_parse->parseValExpr(); + _vm->_game->capturePush(left, top, width, height); + (*_vm->_scenery->_pCaptureCounter)++; + return false; +} + +bool Inter_v1::o1_capturePop(OpFuncParams ¶ms) { + if (*_vm->_scenery->_pCaptureCounter != 0) { + (*_vm->_scenery->_pCaptureCounter)--; + _vm->_game->capturePop(1); } return false; } -bool Inter_v1::o1_setcmdCount(char &cmdCount, int16 &counter, int16 &retFlag) { - cmdCount = *_vm->_global->_inter_execPtr++; - counter = 0; +bool Inter_v1::o1_animPalInit(OpFuncParams ¶ms) { + _animPalDir[0] = load16(); + _animPalLowIndex[0] = _vm->_parse->parseValExpr(); + _animPalHighIndex[0] = _vm->_parse->parseValExpr(); return false; } -bool Inter_v1::o1_return(char &cmdCount, int16 &counter, int16 &retFlag) { - if (retFlag != 2) - _breakFlag = true; +bool Inter_v1::o1_drawOperations(OpFuncParams ¶ms) { + byte cmd; + + cmd = *_vm->_global->_inter_execPtr++; + + executeDrawOpcode(cmd); + + return false; +} + +bool Inter_v1::o1_setcmdCount(OpFuncParams ¶ms) { + params.cmdCount = *_vm->_global->_inter_execPtr++; + params.counter = 0; + return false; +} + +bool Inter_v1::o1_return(OpFuncParams ¶ms) { + if (params.retFlag != 2) + _break = true; _vm->_global->_inter_execPtr = 0; return false; } -bool Inter_v1::o1_renewTimeInVars(char &cmdCount, int16 &counter, int16 &retFlag) { +bool Inter_v1::o1_renewTimeInVars(OpFuncParams ¶ms) { renewTimeInVars(); return false; } -bool Inter_v1::o1_speakerOn(char &cmdCount, int16 &counter, int16 &retFlag) { +bool Inter_v1::o1_speakerOn(OpFuncParams ¶ms) { _vm->_snd->speakerOn(_vm->_parse->parseValExpr(), -1); return false; } -bool Inter_v1::o1_speakerOff(char &cmdCount, int16 &counter, int16 &retFlag) { +bool Inter_v1::o1_speakerOff(OpFuncParams ¶ms) { _vm->_snd->speakerOff(); return false; } -bool Inter_v1::o1_goblinFunc(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 cmd; - int16 extraData = 0; - Goblin::Gob_Object *objDesc = NULL; - int32 *retVarPtr; +bool Inter_v1::o1_putPixel(OpFuncParams ¶ms) { + _vm->_draw->_destSurface = load16(); + + _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); + _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); + _vm->_draw->_frontColor = _vm->_parse->parseValExpr(); + _vm->_draw->spriteOperation(DRAW_PUTPIXEL); + return false; +} + +bool Inter_v1::o1_goblinFunc(OpFuncParams ¶ms) { + OpGobParams gobParams; bool objDescSet = false; + int16 cmd; - retVarPtr = (int32 *)VAR_ADDRESS(59); + gobParams.extraData = 0; + gobParams.objDesc = 0; + gobParams.retVarPtr = (int32 *) VAR_ADDRESS(59); cmd = load16(); _vm->_global->_inter_execPtr += 2; - if (cmd > 0 && cmd < 17) { - extraData = load16(); - objDesc = _vm->_goblin->_objects[extraData]; + if ((cmd > 0) && (cmd < 17)) { objDescSet = true; - extraData = load16(); + gobParams.extraData = load16(); + gobParams.objDesc = _vm->_goblin->_objects[gobParams.extraData]; + gobParams.extraData = load16(); } - if (cmd > 90 && cmd < 107) { - extraData = load16(); - objDesc = _vm->_goblin->_goblins[extraData]; + if ((cmd > 90) && (cmd < 107)) { objDescSet = true; - extraData = load16(); + gobParams.extraData = load16(); + gobParams.objDesc = _vm->_goblin->_goblins[gobParams.extraData]; + gobParams.extraData = load16(); cmd -= 90; } - if (cmd > 110 && cmd < 128) { - extraData = load16(); - objDesc = _vm->_goblin->_goblins[extraData]; + if ((cmd > 110) && (cmd < 128)) { objDescSet = true; + gobParams.extraData = load16(); + gobParams.objDesc = _vm->_goblin->_goblins[gobParams.extraData]; cmd -= 90; - } else if (cmd > 20 && cmd < 38) { - extraData = load16(); - objDesc = _vm->_goblin->_objects[extraData]; + } else if ((cmd > 20) && (cmd < 38)) { objDescSet = true; + gobParams.extraData = load16(); + gobParams.objDesc = _vm->_goblin->_objects[gobParams.extraData]; } /* - NB: The original gobliiins engine did not initialize the objDesc - variable, so we manually check if objDesc is properly set before + NB: The original gobliiins engine did not initialize the gobParams.objDesc + variable, so we manually check if gobParams.objDesc is properly set before checking if it is zero. If it was not set, we do not return. This fixes a crash in the EGA version if the life bar is depleted, because interFunc is called multiple times with cmd == 39. Bug #1324814 */ - if (cmd < 40 && objDescSet && objDesc == 0) + if ((cmd < 40) && objDescSet && !gobParams.objDesc) return false; - executeGoblinOpcode(cmd, extraData, retVarPtr, objDesc); + executeGoblinOpcode(cmd, gobParams); + + return false; +} + +bool Inter_v1::o1_createSprite(OpFuncParams ¶ms) { + int16 index; + int16 width, height; + int16 flag; + + index = load16(); + width = load16(); + height = load16(); + + flag = load16(); + _vm->_draw->initSpriteSurf(index, width, height, flag ? 2 : 0); return false; } -bool Inter_v1::o1_returnTo(char &cmdCount, int16 &counter, int16 &retFlag) { - if (retFlag == 1) { - _breakFlag = true; +bool Inter_v1::o1_freeSprite(OpFuncParams ¶ms) { + _vm->_draw->freeSprite(load16()); + return false; +} + +bool Inter_v1::o1_returnTo(OpFuncParams ¶ms) { + if (params.retFlag == 1) { + _break = true; _vm->_global->_inter_execPtr = 0; return true; } @@ -2093,33 +1883,282 @@ bool Inter_v1::o1_returnTo(char &cmdCount, int16 &counter, int16 &retFlag) { return false; *_breakFromLevel = *_nestLevel; - _breakFlag = true; + _break = true; _vm->_global->_inter_execPtr = 0; return true; } -bool Inter_v1::o1_setBackDelta(char &cmdCount, int16 &counter, int16 &retFlag) { +bool Inter_v1::o1_loadSpriteContent(OpFuncParams ¶ms) { + _vm->_draw->_spriteLeft = load16(); + _vm->_draw->_destSurface = load16(); + _vm->_draw->_transparency = load16(); + _vm->_draw->_destSpriteX = 0; + _vm->_draw->_destSpriteY = 0; + _vm->_draw->spriteOperation(DRAW_LOADSPRITE); + return false; +} + +bool Inter_v1::o1_copySprite(OpFuncParams ¶ms) { + _vm->_draw->_sourceSurface = load16(); + _vm->_draw->_destSurface = load16(); + + _vm->_draw->_spriteLeft = _vm->_parse->parseValExpr(); + _vm->_draw->_spriteTop = _vm->_parse->parseValExpr(); + _vm->_draw->_spriteRight = _vm->_parse->parseValExpr(); + _vm->_draw->_spriteBottom = _vm->_parse->parseValExpr(); + + _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); + _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); + + _vm->_draw->_transparency = load16(); + _vm->_draw->spriteOperation(DRAW_BLITSURF); + return false; +} + +bool Inter_v1::o1_fillRect(OpFuncParams ¶ms) { + _vm->_draw->_destSurface = load16(); + + _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); + _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); + _vm->_draw->_spriteRight = _vm->_parse->parseValExpr(); + _vm->_draw->_spriteBottom = _vm->_parse->parseValExpr(); + + _vm->_draw->_backColor = _vm->_parse->parseValExpr(); + _vm->_draw->spriteOperation(DRAW_FILLRECT); + return false; +} + +bool Inter_v1::o1_drawLine(OpFuncParams ¶ms) { + _vm->_draw->_destSurface = load16(); + + _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); + _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); + _vm->_draw->_spriteRight = _vm->_parse->parseValExpr(); + _vm->_draw->_spriteBottom = _vm->_parse->parseValExpr(); + + _vm->_draw->_frontColor = _vm->_parse->parseValExpr(); + _vm->_draw->spriteOperation(DRAW_DRAWLINE); + return false; +} + +bool Inter_v1::o1_strToLong(OpFuncParams ¶ms) { + char str[20]; + int16 strVar; + int16 destVar; + int32 res; + + strVar = _vm->_parse->parseVarIndex(); + strcpy(str, GET_VARO_STR(strVar)); + res = atol(str); + + destVar = _vm->_parse->parseVarIndex(); + WRITE_VAR_OFFSET(destVar, res); + return false; +} + +bool Inter_v1::o1_invalidate(OpFuncParams ¶ms) { + _vm->_draw->_destSurface = load16(); + _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); + _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); + _vm->_draw->_spriteRight = _vm->_parse->parseValExpr(); + _vm->_draw->_frontColor = _vm->_parse->parseValExpr(); + _vm->_draw->spriteOperation(DRAW_INVALIDATE); + return false; +} + +bool Inter_v1::o1_setBackDelta(OpFuncParams ¶ms) { _vm->_draw->_backDeltaX = _vm->_parse->parseValExpr(); _vm->_draw->_backDeltaY = _vm->_parse->parseValExpr(); return false; } -bool Inter_v1::o1_loadSound(char &cmdCount, int16 &counter, int16 &retFlag) { +bool Inter_v1::o1_playSound(OpFuncParams ¶ms) { + int16 frequency; + int16 freq2; + int16 repCount; + int16 index; + int16 endRep; + + index = _vm->_parse->parseValExpr(); + repCount = _vm->_parse->parseValExpr(); + frequency = _vm->_parse->parseValExpr(); + + SoundDesc &sample = _vm->_game->_soundSamples[index]; + + _soundEndTimeKey = 0; + if (sample.empty()) + return false; + + if (repCount < 0) { + if (_vm->_global->_soundFlags < 2) + return false; + + repCount = -repCount; + _soundEndTimeKey = _vm->_util->getTimeKey(); + + freq2 = frequency ? frequency : sample._frequency; + endRep = MAX(repCount - 1, 1); + + _soundStopVal = sample.calcFadeOutLength(freq2); + _soundEndTimeKey += sample.calcLength(endRep, freq2, true); + } + + if (sample.getType() == SOUND_ADL) { + if (_vm->_adlib) { + _vm->_adlib->load(sample.getData(), sample.size(), index); + _vm->_adlib->setRepeating(repCount - 1); + _vm->_adlib->startPlay(); + } + } else { + _vm->_snd->stopSound(0); + _vm->_snd->playSample(sample, repCount - 1, frequency); + } + + return false; +} + +bool Inter_v1::o1_stopSound(OpFuncParams ¶ms) { + if (_vm->_adlib) + _vm->_adlib->stopPlay(); + _vm->_snd->stopSound(_vm->_parse->parseValExpr()); + + _soundEndTimeKey = 0; + return false; +} + +bool Inter_v1::o1_loadSound(OpFuncParams ¶ms) { loadSound(-1); return false; } -bool Inter_v1::o1_freeSoundSlot(char &cmdCount, int16 &counter, int16 &retFlag) { +bool Inter_v1::o1_freeSoundSlot(OpFuncParams ¶ms) { _vm->_game->freeSoundSlot(-1); return false; } -bool Inter_v1::o1_waitEndPlay(char &cmdCount, int16 &counter, int16 &retFlag) { +bool Inter_v1::o1_waitEndPlay(OpFuncParams ¶ms) { _vm->_snd->waitEndPlay(); return false; } -bool Inter_v1::o1_animatePalette(char &cmdCount, int16 &counter, int16 &retFlag) { +bool Inter_v1::o1_playComposition(OpFuncParams ¶ms) { + int16 composition[50]; + int16 dataVar; + int16 freqVal; + + dataVar = _vm->_parse->parseVarIndex(); + freqVal = _vm->_parse->parseValExpr(); + for (int i = 0; i < 50; i++) + composition[i] = (int16) VAR_OFFSET(dataVar + i * 4); + + _vm->_snd->playComposition(composition, freqVal); + return false; +} + +bool Inter_v1::o1_getFreeMem(OpFuncParams ¶ms) { + int16 freeVar; + int16 maxFreeVar; + + freeVar = _vm->_parse->parseVarIndex(); + maxFreeVar = _vm->_parse->parseVarIndex(); + + // HACK + WRITE_VAR_OFFSET(freeVar, 1000000); + WRITE_VAR_OFFSET(maxFreeVar, 1000000); + return false; +} + +bool Inter_v1::o1_checkData(OpFuncParams ¶ms) { + int16 handle; + int16 varOff; + + evalExpr(0); + varOff = _vm->_parse->parseVarIndex(); + handle = _vm->_dataIO->openData(_vm->_global->_inter_resStr); + + WRITE_VAR_OFFSET(varOff, handle); + if (handle >= 0) + _vm->_dataIO->closeData(handle); + else + warning("File \"%s\" not found", _vm->_global->_inter_resStr); + return false; +} + +bool Inter_v1::o1_prepareStr(OpFuncParams ¶ms) { + int16 strVar; + + strVar = _vm->_parse->parseVarIndex(); + _vm->_util->prepareStr(GET_VARO_STR(strVar)); + _vm->_global->writeVarSizeStr(strVar, strlen(GET_VARO_STR(strVar))); + return false; +} + +bool Inter_v1::o1_insertStr(OpFuncParams ¶ms) { + int16 pos; + int16 strVar; + + strVar = _vm->_parse->parseVarIndex(); + evalExpr(0); + pos = _vm->_parse->parseValExpr(); + _vm->_util->insertStr(_vm->_global->_inter_resStr, GET_VARO_STR(strVar), pos); + _vm->_global->writeVarSizeStr(strVar, strlen(GET_VARO_STR(strVar))); + return false; +} + +bool Inter_v1::o1_cutStr(OpFuncParams ¶ms) { + int16 strVar; + int16 pos; + int16 size; + + strVar = _vm->_parse->parseVarIndex(); + pos = _vm->_parse->parseValExpr(); + size = _vm->_parse->parseValExpr(); + _vm->_util->cutFromStr(GET_VARO_STR(strVar), pos, size); + return false; +} + +bool Inter_v1::o1_strstr(OpFuncParams ¶ms) { + int16 strVar; + int16 resVar; + int16 pos; + + strVar = _vm->_parse->parseVarIndex(); + evalExpr(0); + resVar = _vm->_parse->parseVarIndex(); + + char *res = strstr(GET_VARO_STR(strVar), _vm->_global->_inter_resStr); + pos = res ? (res - (GET_VARO_STR(strVar))) : -1; + WRITE_VAR_OFFSET(resVar, pos); + return false; +} + +bool Inter_v1::o1_istrlen(OpFuncParams ¶ms) { + int16 len; + int16 strVar; + + strVar = _vm->_parse->parseVarIndex(); + len = strlen(GET_VARO_STR(strVar)); + strVar = _vm->_parse->parseVarIndex(); + + WRITE_VAR_OFFSET(strVar, len); + return false; +} + +bool Inter_v1::o1_setMousePos(OpFuncParams ¶ms) { + _vm->_global->_inter_mouseX = _vm->_parse->parseValExpr(); + _vm->_global->_inter_mouseY = _vm->_parse->parseValExpr(); + if (_vm->_global->_useMouse != 0) + _vm->_util->setMousePos(_vm->_global->_inter_mouseX, + _vm->_global->_inter_mouseY); + return false; +} + +bool Inter_v1::o1_setFrameRate(OpFuncParams ¶ms) { + _vm->_util->setFrameRate(_vm->_parse->parseValExpr()); + return false; +} + +bool Inter_v1::o1_animatePalette(OpFuncParams ¶ms) { _vm->_draw->blitInvalidated(); _vm->_util->waitEndFrame(); animPalette(); @@ -2128,174 +2167,279 @@ bool Inter_v1::o1_animatePalette(char &cmdCount, int16 &counter, int16 &retFlag) return false; } -bool Inter_v1::o1_animateCursor(char &cmdCount, int16 &counter, int16 &retFlag) { +bool Inter_v1::o1_animateCursor(OpFuncParams ¶ms) { _vm->_draw->animateCursor(1); return false; } -bool Inter_v1::o1_blitCursor(char &cmdCount, int16 &counter, int16 &retFlag) { +bool Inter_v1::o1_blitCursor(OpFuncParams ¶ms) { _vm->_draw->blitCursor(); return false; } -void Inter_v1::o1_setState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - objDesc->state = extraData; - if (objDesc == _vm->_goblin->_actDestItemDesc) - *_vm->_goblin->_destItemStateVarPtr = extraData; +bool Inter_v1::o1_loadFont(OpFuncParams ¶ms) { + int16 index; + + evalExpr(0); + index = load16(); + + if (_vm->_draw->_fonts[index]) + _vm->_util->freeFont(_vm->_draw->_fonts[index]); + + _vm->_draw->animateCursor(4); + if (_vm->_game->_extHandle >= 0) + _vm->_dataIO->closeData(_vm->_game->_extHandle); + + _vm->_draw->_fonts[index] = + _vm->_util->loadFont(_vm->_global->_inter_resStr); + + if (_vm->_game->_extHandle >= 0) + _vm->_game->_extHandle = _vm->_dataIO->openData(_vm->_game->_curExtFile); + return false; +} + +bool Inter_v1::o1_freeFont(OpFuncParams ¶ms) { + int16 index; + + index = load16(); + if (_vm->_draw->_fonts[index]) + _vm->_util->freeFont(_vm->_draw->_fonts[index]); + + _vm->_draw->_fonts[index] = 0; + return false; +} + +bool Inter_v1::o1_readData(OpFuncParams ¶ms) { + int16 retSize; + int16 size; + int16 dataVar; + int16 offset; + int16 handle; + char buf[4]; + + evalExpr(0); + dataVar = _vm->_parse->parseVarIndex(); + size = _vm->_parse->parseValExpr(); + offset = _vm->_parse->parseValExpr(); + + if (_vm->_game->_extHandle >= 0) + _vm->_dataIO->closeData(_vm->_game->_extHandle); + + WRITE_VAR(1, 1); + handle = _vm->_dataIO->openData(_vm->_global->_inter_resStr); + if (handle >= 0) { + _vm->_draw->animateCursor(4); + if (offset < 0) + _vm->_dataIO->seekData(handle, -offset - 1, 2); + else + _vm->_dataIO->seekData(handle, offset, 0); + + if (((dataVar >> 2) == 59) && (size == 4)) { + retSize = _vm->_dataIO->readData(handle, buf, 4); + WRITE_VAR(59, READ_LE_UINT32(buf)); + } else + retSize = _vm->_dataIO->readData(handle, + _vm->_global->_inter_variables + dataVar, size); + + _vm->_dataIO->closeData(handle); + + if (retSize == size) + WRITE_VAR(1, 0); + } + + if (_vm->_game->_extHandle >= 0) + _vm->_game->_extHandle = _vm->_dataIO->openData(_vm->_game->_curExtFile); + return false; +} + +bool Inter_v1::o1_writeData(OpFuncParams ¶ms) { + int16 offset; + int16 size; + int16 dataVar; + + // This writes into a file. It's not portable and isn't needed anyway + // (Gobliiins 1 doesn't use save file), so we just warn should it be + // called regardless. + + evalExpr(0); + dataVar = _vm->_parse->parseVarIndex(); + size = _vm->_parse->parseValExpr(); + offset = _vm->_parse->parseValExpr(); + + warning("Attempted to write to file \"%s\"", _vm->_global->_inter_resStr); + WRITE_VAR(1, 0); + + return false; } -void Inter_v1::o1_setCurFrame(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - objDesc->curFrame = extraData; - if (objDesc == _vm->_goblin->_actDestItemDesc) - *_vm->_goblin->_destItemFrameVarPtr = extraData; +bool Inter_v1::o1_manageDataFile(OpFuncParams ¶ms) { + evalExpr(0); + + if (_vm->_global->_inter_resStr[0] != 0) + _vm->_dataIO->openDataFile(_vm->_global->_inter_resStr); + else + _vm->_dataIO->closeDataFile(); + return false; } -void Inter_v1::o1_setNextState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - objDesc->nextState = extraData; - if (objDesc == _vm->_goblin->_actDestItemDesc) - *_vm->_goblin->_destItemNextStateVarPtr = extraData; +void Inter_v1::o1_setState(OpGobParams ¶ms) { + params.objDesc->state = params.extraData; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) + *_vm->_goblin->_destItemStateVarPtr = params.extraData; } -void Inter_v1::o1_setMultState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - objDesc->multState = extraData; - if (objDesc == _vm->_goblin->_actDestItemDesc) - *_vm->_goblin->_destItemMultStateVarPtr = extraData; +void Inter_v1::o1_setCurFrame(OpGobParams ¶ms) { + params.objDesc->curFrame = params.extraData; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) + *_vm->_goblin->_destItemFrameVarPtr = params.extraData; } -void Inter_v1::o1_setOrder(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - objDesc->order = extraData; - if (objDesc == _vm->_goblin->_actDestItemDesc) - *_vm->_goblin->_destItemOrderVarPtr = extraData; +void Inter_v1::o1_setNextState(OpGobParams ¶ms) { + params.objDesc->nextState = params.extraData; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) + *_vm->_goblin->_destItemNextStateVarPtr = params.extraData; } -void Inter_v1::o1_setActionStartState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - objDesc->actionStartState = extraData; - if (objDesc == _vm->_goblin->_actDestItemDesc) - *_vm->_goblin->_destItemActStartStVarPtr = extraData; +void Inter_v1::o1_setMultState(OpGobParams ¶ms) { + params.objDesc->multState = params.extraData; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) + *_vm->_goblin->_destItemMultStateVarPtr = params.extraData; } -void Inter_v1::o1_setCurLookDir(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - objDesc->curLookDir = extraData; - if (objDesc == _vm->_goblin->_actDestItemDesc) - *_vm->_goblin->_destItemLookDirVarPtr = extraData; +void Inter_v1::o1_setOrder(OpGobParams ¶ms) { + params.objDesc->order = params.extraData; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) + *_vm->_goblin->_destItemOrderVarPtr = params.extraData; } -void Inter_v1::o1_setType(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - objDesc->type = extraData; - if (objDesc == _vm->_goblin->_actDestItemDesc) - *_vm->_goblin->_destItemTypeVarPtr = extraData; +void Inter_v1::o1_setActionStartState(OpGobParams ¶ms) { + params.objDesc->actionStartState = params.extraData; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) + *_vm->_goblin->_destItemActStartStVarPtr = params.extraData; +} - if (extraData == 0) - objDesc->toRedraw = 1; +void Inter_v1::o1_setCurLookDir(OpGobParams ¶ms) { + params.objDesc->curLookDir = params.extraData; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) + *_vm->_goblin->_destItemLookDirVarPtr = params.extraData; } -void Inter_v1::o1_setNoTick(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - objDesc->noTick = extraData; - if (objDesc == _vm->_goblin->_actDestItemDesc) - *_vm->_goblin->_destItemNoTickVarPtr = extraData; +void Inter_v1::o1_setType(OpGobParams ¶ms) { + params.objDesc->type = params.extraData; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) + *_vm->_goblin->_destItemTypeVarPtr = params.extraData; + + if (params.extraData == 0) + params.objDesc->toRedraw = 1; } -void Inter_v1::o1_setPickable(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - objDesc->pickable = extraData; - if (objDesc == _vm->_goblin->_actDestItemDesc) - *_vm->_goblin->_destItemPickableVarPtr = extraData; +void Inter_v1::o1_setNoTick(OpGobParams ¶ms) { + params.objDesc->noTick = params.extraData; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) + *_vm->_goblin->_destItemNoTickVarPtr = params.extraData; } -void Inter_v1::o1_setXPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - objDesc->xPos = extraData; - if (objDesc == _vm->_goblin->_actDestItemDesc) - *_vm->_goblin->_destItemScrXVarPtr = extraData; +void Inter_v1::o1_setPickable(OpGobParams ¶ms) { + params.objDesc->pickable = params.extraData; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) + *_vm->_goblin->_destItemPickableVarPtr = params.extraData; } -void Inter_v1::o1_setYPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - objDesc->yPos = extraData; - if (objDesc == _vm->_goblin->_actDestItemDesc) - *_vm->_goblin->_destItemScrYVarPtr = extraData; +void Inter_v1::o1_setXPos(OpGobParams ¶ms) { + params.objDesc->xPos = params.extraData; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) + *_vm->_goblin->_destItemScrXVarPtr = params.extraData; } -void Inter_v1::o1_setDoAnim(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - objDesc->doAnim = extraData; - if (objDesc == _vm->_goblin->_actDestItemDesc) - *_vm->_goblin->_destItemDoAnimVarPtr = extraData; +void Inter_v1::o1_setYPos(OpGobParams ¶ms) { + params.objDesc->yPos = params.extraData; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) + *_vm->_goblin->_destItemScrYVarPtr = params.extraData; } -void Inter_v1::o1_setRelaxTime(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - objDesc->relaxTime = extraData; - if (objDesc == _vm->_goblin->_actDestItemDesc) - *_vm->_goblin->_destItemRelaxVarPtr = extraData; +void Inter_v1::o1_setDoAnim(OpGobParams ¶ms) { + params.objDesc->doAnim = params.extraData; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) + *_vm->_goblin->_destItemDoAnimVarPtr = params.extraData; } -void Inter_v1::o1_setMaxTick(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - objDesc->maxTick = extraData; - if (objDesc == _vm->_goblin->_actDestItemDesc) - *_vm->_goblin->_destItemMaxTickVarPtr = extraData; +void Inter_v1::o1_setRelaxTime(OpGobParams ¶ms) { + params.objDesc->relaxTime = params.extraData; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) + *_vm->_goblin->_destItemRelaxVarPtr = params.extraData; } -void Inter_v1::o1_getState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = objDesc->state; +void Inter_v1::o1_setMaxTick(OpGobParams ¶ms) { + params.objDesc->maxTick = params.extraData; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) + *_vm->_goblin->_destItemMaxTickVarPtr = params.extraData; } -void Inter_v1::o1_getCurFrame(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = objDesc->curFrame; +void Inter_v1::o1_getState(OpGobParams ¶ms) { + *params.retVarPtr = params.objDesc->state; } -void Inter_v1::o1_getNextState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = objDesc->nextState; +void Inter_v1::o1_getCurFrame(OpGobParams ¶ms) { + *params.retVarPtr = params.objDesc->curFrame; } -void Inter_v1::o1_getMultState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = objDesc->multState; +void Inter_v1::o1_getNextState(OpGobParams ¶ms) { + *params.retVarPtr = params.objDesc->nextState; } -void Inter_v1::o1_getOrder(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = objDesc->order; +void Inter_v1::o1_getMultState(OpGobParams ¶ms) { + *params.retVarPtr = params.objDesc->multState; } -void Inter_v1::o1_getActionStartState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = objDesc->actionStartState; +void Inter_v1::o1_getOrder(OpGobParams ¶ms) { + *params.retVarPtr = params.objDesc->order; } -void Inter_v1::o1_getCurLookDir(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = objDesc->curLookDir; +void Inter_v1::o1_getActionStartState(OpGobParams ¶ms) { + *params.retVarPtr = params.objDesc->actionStartState; } -void Inter_v1::o1_getType(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = objDesc->type; +void Inter_v1::o1_getCurLookDir(OpGobParams ¶ms) { + *params.retVarPtr = params.objDesc->curLookDir; } -void Inter_v1::o1_getNoTick(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = objDesc->noTick; +void Inter_v1::o1_getType(OpGobParams ¶ms) { + *params.retVarPtr = params.objDesc->type; } -void Inter_v1::o1_getPickable(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = objDesc->pickable; +void Inter_v1::o1_getNoTick(OpGobParams ¶ms) { + *params.retVarPtr = params.objDesc->noTick; } -void Inter_v1::o1_getObjMaxFrame(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = _vm->_goblin->getObjMaxFrame(objDesc); +void Inter_v1::o1_getPickable(OpGobParams ¶ms) { + *params.retVarPtr = params.objDesc->pickable; } -void Inter_v1::o1_getXPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = objDesc->xPos; +void Inter_v1::o1_getObjMaxFrame(OpGobParams ¶ms) { + *params.retVarPtr = _vm->_goblin->getObjMaxFrame(params.objDesc); } -void Inter_v1::o1_getYPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = objDesc->yPos; +void Inter_v1::o1_getXPos(OpGobParams ¶ms) { + *params.retVarPtr = params.objDesc->xPos; } -void Inter_v1::o1_getDoAnim(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = objDesc->doAnim; +void Inter_v1::o1_getYPos(OpGobParams ¶ms) { + *params.retVarPtr = params.objDesc->yPos; } -void Inter_v1::o1_getRelaxTime(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = objDesc->relaxTime; +void Inter_v1::o1_getDoAnim(OpGobParams ¶ms) { + *params.retVarPtr = params.objDesc->doAnim; } -void Inter_v1::o1_getMaxTick(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = objDesc->maxTick; +void Inter_v1::o1_getRelaxTime(OpGobParams ¶ms) { + *params.retVarPtr = params.objDesc->relaxTime; } -void Inter_v1::o1_manipulateMap(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_getMaxTick(OpGobParams ¶ms) { + *params.retVarPtr = params.objDesc->maxTick; +} + +void Inter_v1::o1_manipulateMap(OpGobParams ¶ms) { int16 xPos = load16(); int16 yPos = load16(); int16 item = load16(); @@ -2303,17 +2447,17 @@ void Inter_v1::o1_manipulateMap(int16 &extraData, int32 *retVarPtr, Goblin::Gob_ manipulateMap(xPos, yPos, item); } -void Inter_v1::o1_getItem(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_getItem(OpGobParams ¶ms) { int16 xPos = load16(); int16 yPos = load16(); - if ((_vm->_map->_itemsMap[yPos][xPos] & 0xff00) != 0) - *retVarPtr = (_vm->_map->_itemsMap[yPos][xPos] & 0xff00) >> 8; + if ((_vm->_map->_itemsMap[yPos][xPos] & 0xFF00) != 0) + *params.retVarPtr = (_vm->_map->_itemsMap[yPos][xPos] & 0xFF00) >> 8; else - *retVarPtr = _vm->_map->_itemsMap[yPos][xPos]; + *params.retVarPtr = _vm->_map->_itemsMap[yPos][xPos]; } -void Inter_v1::o1_manipulateMapIndirect(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_manipulateMapIndirect(OpGobParams ¶ms) { int16 xPos = load16(); int16 yPos = load16(); int16 item = load16(); @@ -2325,27 +2469,27 @@ void Inter_v1::o1_manipulateMapIndirect(int16 &extraData, int32 *retVarPtr, Gobl manipulateMap(xPos, yPos, item); } -void Inter_v1::o1_getItemIndirect(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_getItemIndirect(OpGobParams ¶ms) { int16 xPos = load16(); int16 yPos = load16(); xPos = VAR(xPos); yPos = VAR(yPos); - if ((_vm->_map->_itemsMap[yPos][xPos] & 0xff00) != 0) - *retVarPtr = (_vm->_map->_itemsMap[yPos][xPos] & 0xff00) >> 8; + if ((_vm->_map->_itemsMap[yPos][xPos] & 0xFF00) != 0) + *params.retVarPtr = (_vm->_map->_itemsMap[yPos][xPos] & 0xFF00) >> 8; else - *retVarPtr = _vm->_map->_itemsMap[yPos][xPos]; + *params.retVarPtr = _vm->_map->_itemsMap[yPos][xPos]; } -void Inter_v1::o1_setPassMap(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_setPassMap(OpGobParams ¶ms) { int16 xPos = load16(); int16 yPos = load16(); int16 val = load16(); _vm->_map->setPass(xPos, yPos, val); } -void Inter_v1::o1_setGoblinPosH(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_setGoblinPosH(OpGobParams ¶ms) { int16 layer; int16 item = load16(); int16 xPos = load16(); @@ -2354,28 +2498,27 @@ void Inter_v1::o1_setGoblinPosH(int16 &extraData, int32 *retVarPtr, Goblin::Gob_ _vm->_goblin->_gobPositions[item].x = xPos * 2; _vm->_goblin->_gobPositions[item].y = yPos * 2; - objDesc = _vm->_goblin->_goblins[item]; - objDesc->nextState = 21; + params.objDesc = _vm->_goblin->_goblins[item]; + params.objDesc->nextState = 21; - _vm->_goblin->nextLayer(objDesc); + _vm->_goblin->nextLayer(params.objDesc); - layer = objDesc->stateMach[objDesc->state][0]->layer; + layer = params.objDesc->stateMach[params.objDesc->state][0]->layer; - _vm->_scenery->updateAnim(layer, 0, objDesc->animation, 0, - objDesc->xPos, objDesc->yPos, 0); + _vm->_scenery->updateAnim(layer, 0, params.objDesc->animation, 0, + params.objDesc->xPos, params.objDesc->yPos, 0); - objDesc->yPos = - (_vm->_goblin->_gobPositions[item].y * 6 + 6) - (_vm->_scenery->_toRedrawBottom - - _vm->_scenery->_animTop); - objDesc->xPos = - _vm->_goblin->_gobPositions[item].x * 12 - (_vm->_scenery->_toRedrawLeft - - _vm->_scenery->_animLeft); + params.objDesc->yPos = (_vm->_goblin->_gobPositions[item].y * 6 + 6) - + (_vm->_scenery->_toRedrawBottom - _vm->_scenery->_animTop); + params.objDesc->xPos = + _vm->_goblin->_gobPositions[item].x * 12 - + (_vm->_scenery->_toRedrawLeft - _vm->_scenery->_animLeft); - objDesc->curFrame = 0; - objDesc->state = 21; + params.objDesc->curFrame = 0; + params.objDesc->state = 21; if (_vm->_goblin->_currentGoblin == item) { - *_vm->_goblin->_curGobScrXVarPtr = objDesc->xPos; - *_vm->_goblin->_curGobScrYVarPtr = objDesc->yPos; + *_vm->_goblin->_curGobScrXVarPtr = params.objDesc->xPos; + *_vm->_goblin->_curGobScrYVarPtr = params.objDesc->yPos; *_vm->_goblin->_curGobFrameVarPtr = 0; *_vm->_goblin->_curGobStateVarPtr = 18; @@ -2384,60 +2527,60 @@ void Inter_v1::o1_setGoblinPosH(int16 &extraData, int32 *retVarPtr, Goblin::Gob_ } } -void Inter_v1::o1_getGoblinPosXH(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_getGoblinPosXH(OpGobParams ¶ms) { int16 item = load16(); - *retVarPtr = _vm->_goblin->_gobPositions[item].x >> 1; + *params.retVarPtr = _vm->_goblin->_gobPositions[item].x >> 1; } -void Inter_v1::o1_getGoblinPosYH(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_getGoblinPosYH(OpGobParams ¶ms) { int16 item = load16(); - *retVarPtr = _vm->_goblin->_gobPositions[item].y >> 1; + *params.retVarPtr = _vm->_goblin->_gobPositions[item].y >> 1; } -void Inter_v1::o1_setGoblinMultState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_setGoblinMultState(OpGobParams ¶ms) { int16 layer; int16 item = load16(); int16 xPos = load16(); int16 yPos = load16(); - objDesc = _vm->_goblin->_goblins[item]; + params.objDesc = _vm->_goblin->_goblins[item]; if (yPos == 0) { - objDesc->multState = xPos; - objDesc->nextState = xPos; - _vm->_goblin->nextLayer(objDesc); + params.objDesc->multState = xPos; + params.objDesc->nextState = xPos; + _vm->_goblin->nextLayer(params.objDesc); - layer = objDesc->stateMach[objDesc->state][0]->layer; + layer = params.objDesc->stateMach[params.objDesc->state][0]->layer; - objDesc->xPos = - _vm->_scenery->_animations[objDesc->animation].layers[layer].posX; - objDesc->yPos = - _vm->_scenery->_animations[objDesc->animation].layers[layer].posY; + Scenery::AnimLayer *animLayer = + _vm->_scenery->getAnimLayer(params.objDesc->animation, layer); + params.objDesc->xPos = animLayer->posX; + params.objDesc->yPos = animLayer->posY; - *_vm->_goblin->_curGobScrXVarPtr = objDesc->xPos; - *_vm->_goblin->_curGobScrYVarPtr = objDesc->yPos; + *_vm->_goblin->_curGobScrXVarPtr = params.objDesc->xPos; + *_vm->_goblin->_curGobScrYVarPtr = params.objDesc->yPos; *_vm->_goblin->_curGobFrameVarPtr = 0; - *_vm->_goblin->_curGobStateVarPtr = objDesc->state; - *_vm->_goblin->_curGobNextStateVarPtr = objDesc->nextState; - *_vm->_goblin->_curGobMultStateVarPtr = objDesc->multState; + *_vm->_goblin->_curGobStateVarPtr = params.objDesc->state; + *_vm->_goblin->_curGobNextStateVarPtr = params.objDesc->nextState; + *_vm->_goblin->_curGobMultStateVarPtr = params.objDesc->multState; *_vm->_goblin->_curGobMaxFrameVarPtr = - _vm->_goblin->getObjMaxFrame(objDesc); + _vm->_goblin->getObjMaxFrame(params.objDesc); _vm->_goblin->_noPick = 1; return; } - objDesc->multState = 21; - objDesc->nextState = 21; - objDesc->state = 21; - _vm->_goblin->nextLayer(objDesc); - layer = objDesc->stateMach[objDesc->state][0]->layer; + params.objDesc->multState = 21; + params.objDesc->nextState = 21; + params.objDesc->state = 21; + _vm->_goblin->nextLayer(params.objDesc); + layer = params.objDesc->stateMach[params.objDesc->state][0]->layer; - _vm->_scenery->updateAnim(layer, 0, objDesc->animation, 0, - objDesc->xPos, objDesc->yPos, 0); + _vm->_scenery->updateAnim(layer, 0, params.objDesc->animation, 0, + params.objDesc->xPos, params.objDesc->yPos, 0); - objDesc->yPos = - (yPos * 6 + 6) - (_vm->_scenery->_toRedrawBottom - _vm->_scenery->_animTop); - objDesc->xPos = - xPos * 12 - (_vm->_scenery->_toRedrawLeft - _vm->_scenery->_animLeft); + params.objDesc->yPos = (yPos * 6 + 6) - + (_vm->_scenery->_toRedrawBottom - _vm->_scenery->_animTop); + params.objDesc->xPos = xPos * 12 - + (_vm->_scenery->_toRedrawLeft - _vm->_scenery->_animLeft); _vm->_goblin->_gobPositions[item].x = xPos; _vm->_goblin->_pressedMapX = xPos; @@ -2447,8 +2590,8 @@ void Inter_v1::o1_setGoblinMultState(int16 &extraData, int32 *retVarPtr, Goblin: _vm->_goblin->_pressedMapY = yPos; _vm->_map->_curGoblinY = yPos; - *_vm->_goblin->_curGobScrXVarPtr = objDesc->xPos; - *_vm->_goblin->_curGobScrYVarPtr = objDesc->yPos; + *_vm->_goblin->_curGobScrXVarPtr = params.objDesc->xPos; + *_vm->_goblin->_curGobScrYVarPtr = params.objDesc->yPos; *_vm->_goblin->_curGobFrameVarPtr = 0; *_vm->_goblin->_curGobStateVarPtr = 21; *_vm->_goblin->_curGobNextStateVarPtr = 21; @@ -2456,7 +2599,30 @@ void Inter_v1::o1_setGoblinMultState(int16 &extraData, int32 *retVarPtr, Goblin: _vm->_goblin->_noPick = 0; } -void Inter_v1::o1_setGoblinPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_setGoblinUnk14(OpGobParams ¶ms) { + int16 item = load16(); + int16 val = load16(); + params.objDesc = _vm->_goblin->_objects[item]; + params.objDesc->unk14 = val; +} + +void Inter_v1::o1_setItemIdInPocket(OpGobParams ¶ms) { + _vm->_goblin->_itemIdInPocket = load16(); +} + +void Inter_v1::o1_setItemIndInPocket(OpGobParams ¶ms) { + _vm->_goblin->_itemIndInPocket = load16(); +} + +void Inter_v1::o1_getItemIdInPocket(OpGobParams ¶ms) { + *params.retVarPtr = _vm->_goblin->_itemIdInPocket; +} + +void Inter_v1::o1_getItemIndInPocket(OpGobParams ¶ms) { + *params.retVarPtr = _vm->_goblin->_itemIndInPocket; +} + +void Inter_v1::o1_setGoblinPos(OpGobParams ¶ms) { int16 layer; int16 item = load16(); int16 xPos = load16(); @@ -2465,26 +2631,26 @@ void Inter_v1::o1_setGoblinPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_O _vm->_goblin->_gobPositions[item].x = xPos; _vm->_goblin->_gobPositions[item].y = yPos; - objDesc = _vm->_goblin->_goblins[item]; - objDesc->nextState = 21; - _vm->_goblin->nextLayer(objDesc); + params.objDesc = _vm->_goblin->_goblins[item]; + params.objDesc->nextState = 21; + _vm->_goblin->nextLayer(params.objDesc); - layer = objDesc->stateMach[objDesc->state][0]->layer; + layer = params.objDesc->stateMach[params.objDesc->state][0]->layer; - _vm->_scenery->updateAnim(layer, 0, objDesc->animation, 0, - objDesc->xPos, objDesc->yPos, 0); + _vm->_scenery->updateAnim(layer, 0, params.objDesc->animation, 0, + params.objDesc->xPos, params.objDesc->yPos, 0); - objDesc->yPos = - (yPos * 6 + 6) - (_vm->_scenery->_toRedrawBottom - _vm->_scenery->_animTop); - objDesc->xPos = - xPos * 12 - (_vm->_scenery->_toRedrawLeft - _vm->_scenery->_animLeft); + params.objDesc->yPos = (yPos * 6 + 6) - + (_vm->_scenery->_toRedrawBottom - _vm->_scenery->_animTop); + params.objDesc->xPos = xPos * 12 - + (_vm->_scenery->_toRedrawLeft - _vm->_scenery->_animLeft); - objDesc->curFrame = 0; - objDesc->state = 21; + params.objDesc->curFrame = 0; + params.objDesc->state = 21; if (_vm->_goblin->_currentGoblin == item) { - *_vm->_goblin->_curGobScrXVarPtr = objDesc->xPos; - *_vm->_goblin->_curGobScrYVarPtr = objDesc->yPos; + *_vm->_goblin->_curGobScrXVarPtr = params.objDesc->xPos; + *_vm->_goblin->_curGobScrYVarPtr = params.objDesc->yPos; *_vm->_goblin->_curGobFrameVarPtr = 0; *_vm->_goblin->_curGobStateVarPtr = 18; @@ -2493,170 +2659,151 @@ void Inter_v1::o1_setGoblinPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_O } } -void Inter_v1::o1_setGoblinState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_setGoblinState(OpGobParams ¶ms) { int16 layer; int16 item = load16(); int16 state = load16(); - objDesc = _vm->_goblin->_goblins[item]; - objDesc->nextState = state; + params.objDesc = _vm->_goblin->_goblins[item]; + params.objDesc->nextState = state; - _vm->_goblin->nextLayer(objDesc); - layer = objDesc->stateMach[objDesc->state][0]->layer; + _vm->_goblin->nextLayer(params.objDesc); + layer = params.objDesc->stateMach[params.objDesc->state][0]->layer; - objDesc->xPos = - _vm->_scenery->_animations[objDesc->animation].layers[layer].posX; - objDesc->yPos = - _vm->_scenery->_animations[objDesc->animation].layers[layer].posY; + Scenery::AnimLayer *animLayer = + _vm->_scenery->getAnimLayer(params.objDesc->animation, layer); + params.objDesc->xPos = animLayer->posX; + params.objDesc->yPos = animLayer->posY; if (item == _vm->_goblin->_currentGoblin) { - *_vm->_goblin->_curGobScrXVarPtr = objDesc->xPos; - *_vm->_goblin->_curGobScrYVarPtr = objDesc->yPos; + *_vm->_goblin->_curGobScrXVarPtr = params.objDesc->xPos; + *_vm->_goblin->_curGobScrYVarPtr = params.objDesc->yPos; *_vm->_goblin->_curGobFrameVarPtr = 0; - *_vm->_goblin->_curGobStateVarPtr = objDesc->state; - *_vm->_goblin->_curGobMultStateVarPtr = objDesc->multState; + *_vm->_goblin->_curGobStateVarPtr = params.objDesc->state; + *_vm->_goblin->_curGobMultStateVarPtr = params.objDesc->multState; } } -void Inter_v1::o1_setGoblinStateRedraw(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_setGoblinStateRedraw(OpGobParams ¶ms) { int16 layer; int16 item = load16(); int16 state = load16(); - objDesc = _vm->_goblin->_objects[item]; + params.objDesc = _vm->_goblin->_objects[item]; + + params.objDesc->nextState = state; - objDesc->nextState = state; + _vm->_goblin->nextLayer(params.objDesc); + layer = params.objDesc->stateMach[params.objDesc->state][0]->layer; - _vm->_goblin->nextLayer(objDesc); - layer = objDesc->stateMach[objDesc->state][0]->layer; - objDesc->xPos = - _vm->_scenery->_animations[objDesc->animation].layers[layer].posX; - objDesc->yPos = - _vm->_scenery->_animations[objDesc->animation].layers[layer].posY; + Scenery::AnimLayer *animLayer = + _vm->_scenery->getAnimLayer(params.objDesc->animation, layer); + params.objDesc->xPos = animLayer->posX; + params.objDesc->yPos = animLayer->posY; - objDesc->toRedraw = 1; - objDesc->type = 0; - if (objDesc == _vm->_goblin->_actDestItemDesc) { - *_vm->_goblin->_destItemScrXVarPtr = objDesc->xPos; - *_vm->_goblin->_destItemScrYVarPtr = objDesc->yPos; + params.objDesc->toRedraw = 1; + params.objDesc->type = 0; + if (params.objDesc == _vm->_goblin->_actDestItemDesc) { + *_vm->_goblin->_destItemScrXVarPtr = params.objDesc->xPos; + *_vm->_goblin->_destItemScrYVarPtr = params.objDesc->yPos; - *_vm->_goblin->_destItemStateVarPtr = objDesc->state; + *_vm->_goblin->_destItemStateVarPtr = params.objDesc->state; *_vm->_goblin->_destItemNextStateVarPtr = -1; *_vm->_goblin->_destItemMultStateVarPtr = -1; *_vm->_goblin->_destItemFrameVarPtr = 0; } } -void Inter_v1::o1_setGoblinUnk14(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - int16 item = load16(); - int16 val = load16(); - objDesc = _vm->_goblin->_objects[item]; - objDesc->unk14 = val; -} - -void Inter_v1::o1_setItemIdInPocket(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - _vm->_goblin->_itemIdInPocket = load16(); -} - -void Inter_v1::o1_setItemIndInPocket(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - _vm->_goblin->_itemIndInPocket = load16(); -} - -void Inter_v1::o1_getItemIdInPocket(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = _vm->_goblin->_itemIdInPocket; -} - -void Inter_v1::o1_getItemIndInPocket(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - *retVarPtr = _vm->_goblin->_itemIndInPocket; -} +void Inter_v1::o1_decRelaxTime(OpGobParams ¶ms) { + params.extraData = load16(); + params.objDesc = _vm->_goblin->_objects[params.extraData]; -void Inter_v1::o1_setItemPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - int16 item = load16(); - int16 xPos = load16(); - int16 yPos = load16(); - int16 val = load16(); - - _vm->_map->_itemPoses[item].x = xPos; - _vm->_map->_itemPoses[item].y = yPos; - _vm->_map->_itemPoses[item].orient = val; -} - -void Inter_v1::o1_decRelaxTime(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - extraData = load16(); - objDesc = _vm->_goblin->_objects[extraData]; - - objDesc->relaxTime--; - if (objDesc->relaxTime < 0 && - _vm->_goblin->getObjMaxFrame(objDesc) == objDesc->curFrame) { - objDesc->relaxTime = _vm->_util->getRandom(100) + 50; - objDesc->curFrame = 0; - objDesc->toRedraw = 1; + params.objDesc->relaxTime--; + if ((params.objDesc->relaxTime < 0) && + (_vm->_goblin->getObjMaxFrame(params.objDesc) == + params.objDesc->curFrame)) { + params.objDesc->relaxTime = _vm->_util->getRandom(100) + 50; + params.objDesc->curFrame = 0; + params.objDesc->toRedraw = 1; } } -void Inter_v1::o1_getGoblinPosX(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_getGoblinPosX(OpGobParams ¶ms) { int16 item = load16(); - *retVarPtr = _vm->_goblin->_gobPositions[item].x; + *params.retVarPtr = _vm->_goblin->_gobPositions[item].x; } -void Inter_v1::o1_getGoblinPosY(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_getGoblinPosY(OpGobParams ¶ms) { int16 item = load16(); - *retVarPtr = _vm->_goblin->_gobPositions[item].y; + *params.retVarPtr = _vm->_goblin->_gobPositions[item].y; } -void Inter_v1::o1_clearPathExistence(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_clearPathExistence(OpGobParams ¶ms) { _vm->_goblin->_pathExistence = 0; } -void Inter_v1::o1_setGoblinVisible(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - extraData = load16(); - _vm->_goblin->_goblins[extraData]->visible = 1; +void Inter_v1::o1_setGoblinVisible(OpGobParams ¶ms) { + params.extraData = load16(); + _vm->_goblin->_goblins[params.extraData]->visible = 1; } -void Inter_v1::o1_setGoblinInvisible(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - extraData = load16(); - _vm->_goblin->_goblins[extraData]->visible = 0; +void Inter_v1::o1_setGoblinInvisible(OpGobParams ¶ms) { + params.extraData = load16(); + _vm->_goblin->_goblins[params.extraData]->visible = 0; } -void Inter_v1::o1_getObjectIntersect(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - extraData = load16(); +void Inter_v1::o1_getObjectIntersect(OpGobParams ¶ms) { + params.extraData = load16(); int16 item = load16(); - objDesc = _vm->_goblin->_objects[extraData]; - if (_vm->_goblin->objIntersected(objDesc, _vm->_goblin->_goblins[item]) != 0) - *retVarPtr = 1; + params.objDesc = _vm->_goblin->_objects[params.extraData]; + if (_vm->_goblin->objIntersected(params.objDesc, + _vm->_goblin->_goblins[item])) + *params.retVarPtr = 1; else - *retVarPtr = 0; + *params.retVarPtr = 0; } -void Inter_v1::o1_getGoblinIntersect(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - extraData = load16(); +void Inter_v1::o1_getGoblinIntersect(OpGobParams ¶ms) { + params.extraData = load16(); int16 item = load16(); - objDesc = _vm->_goblin->_goblins[extraData]; - if (_vm->_goblin->objIntersected(objDesc, _vm->_goblin->_goblins[item]) != 0) - *retVarPtr = 1; + params.objDesc = _vm->_goblin->_goblins[params.extraData]; + if (_vm->_goblin->objIntersected(params.objDesc, + _vm->_goblin->_goblins[item])) + *params.retVarPtr = 1; else - *retVarPtr = 0; + *params.retVarPtr = 0; +} + +void Inter_v1::o1_setItemPos(OpGobParams ¶ms) { + int16 item = load16(); + int16 xPos = load16(); + int16 yPos = load16(); + int16 val = load16(); + + _vm->_map->_itemPoses[item].x = xPos; + _vm->_map->_itemPoses[item].y = yPos; + _vm->_map->_itemPoses[item].orient = val; } -void Inter_v1::o1_loadObjects(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - extraData = load16(); +void Inter_v1::o1_loadObjects(OpGobParams ¶ms) { + params.extraData = load16(); if (_vm->_game->_extHandle >= 0) - _vm->_dataio->closeData(_vm->_game->_extHandle); + _vm->_dataIO->closeData(_vm->_game->_extHandle); - _vm->_goblin->loadObjects((char *)VAR_ADDRESS(extraData)); - _vm->_game->_extHandle = _vm->_dataio->openData(_vm->_game->_curExtFile); + _vm->_goblin->loadObjects((char *) VAR_ADDRESS(params.extraData)); + _vm->_game->_extHandle = _vm->_dataIO->openData(_vm->_game->_curExtFile); } -void Inter_v1::o1_freeObjects(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_freeObjects(OpGobParams ¶ms) { _vm->_goblin->freeAllObjects(); } -void Inter_v1::o1_animateObjects(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_animateObjects(OpGobParams ¶ms) { _vm->_goblin->animateObjects(); } -void Inter_v1::o1_drawObjects(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_drawObjects(OpGobParams ¶ms) { _vm->_goblin->drawObjects(); if (_vm->_platform == Common::kPlatformMacintosh) { @@ -2666,72 +2813,74 @@ void Inter_v1::o1_drawObjects(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Ob _vm->_cdrom->playBgMusic(); } -void Inter_v1::o1_loadMap(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_loadMap(OpGobParams ¶ms) { _vm->_map->loadMapsInitGobs(); } -void Inter_v1::o1_moveGoblin(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_moveGoblin(OpGobParams ¶ms) { int16 item; - extraData = load16(); + params.extraData = load16(); int16 xPos = load16(); - if ((uint16)VAR(xPos) == 0) { + if ((uint16) VAR(xPos) == 0) { item = - _vm->_goblin->doMove(_vm->_goblin->_goblins[_vm->_goblin->_currentGoblin], 1, - (uint16)VAR(extraData)); + _vm->_goblin->doMove(_vm->_goblin->_goblins[_vm->_goblin->_currentGoblin], + 1, (uint16) VAR(params.extraData)); } else { item = - _vm->_goblin->doMove(_vm->_goblin->_goblins[_vm->_goblin->_currentGoblin], 1, 3); + _vm->_goblin->doMove(_vm->_goblin->_goblins[_vm->_goblin->_currentGoblin], + 1, 3); } if (item != 0) _vm->_goblin->switchGoblin(item); } -void Inter_v1::o1_switchGoblin(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_switchGoblin(OpGobParams ¶ms) { _vm->_goblin->switchGoblin(0); } -void Inter_v1::o1_loadGoblin(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_loadGoblin(OpGobParams ¶ms) { _vm->_goblin->loadGobDataFromVars(); } -void Inter_v1::o1_writeTreatItem(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - extraData = load16(); +void Inter_v1::o1_writeTreatItem(OpGobParams ¶ms) { + params.extraData = load16(); int16 cmd = load16(); int16 xPos = load16(); - if ((uint16)VAR(xPos) == 0) { - WRITE_VAR(cmd, _vm->_goblin->treatItem((uint16)VAR(extraData))); + if ((uint16) VAR(xPos) == 0) { + WRITE_VAR(cmd, _vm->_goblin->treatItem((uint16) VAR(params.extraData))); return; } WRITE_VAR(cmd, _vm->_goblin->treatItem(3)); } -void Inter_v1::o1_moveGoblin0(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - _vm->_goblin->doMove(_vm->_goblin->_goblins[_vm->_goblin->_currentGoblin], 0, 0); +void Inter_v1::o1_moveGoblin0(OpGobParams ¶ms) { + _vm->_goblin->doMove(_vm->_goblin->_goblins[_vm->_goblin->_currentGoblin], + 0, 0); } -void Inter_v1::o1_setGoblinTarget(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - extraData = load16(); - if (VAR(extraData) != 0) +void Inter_v1::o1_setGoblinTarget(OpGobParams ¶ms) { + params.extraData = load16(); + if (VAR(params.extraData) != 0) _vm->_goblin->_goesAtTarget = 1; else _vm->_goblin->_goesAtTarget = 0; } -void Inter_v1::o1_setGoblinObjectsPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - extraData = load16(); - extraData = VAR(extraData); - _vm->_goblin->_objects[10]->xPos = extraData; +void Inter_v1::o1_setGoblinObjectsPos(OpGobParams ¶ms) { + params.extraData = load16(); + params.extraData = VAR(params.extraData); + _vm->_goblin->_objects[10]->xPos = params.extraData; - extraData = load16(); - extraData = VAR(extraData); - _vm->_goblin->_objects[10]->yPos = extraData; + params.extraData = load16(); + params.extraData = VAR(params.extraData); + _vm->_goblin->_objects[10]->yPos = params.extraData; } -void Inter_v1::o1_initGoblin(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { +void Inter_v1::o1_initGoblin(OpGobParams ¶ms) { Goblin::Gob_Object *gobDesc = _vm->_goblin->_goblins[0]; int16 xPos; int16 yPos; @@ -2761,8 +2910,8 @@ void Inter_v1::o1_initGoblin(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Obj _vm->_goblin->_readyToAct = 0; } - if (gobDesc->state != 10 && _vm->_goblin->_itemIndInPocket != -1 && - _vm->_goblin->getObjMaxFrame(gobDesc) == gobDesc->curFrame) { + if ((gobDesc->state != 10) && (_vm->_goblin->_itemIndInPocket != -1) && + (_vm->_goblin->getObjMaxFrame(gobDesc) == gobDesc->curFrame)) { gobDesc->stateMach = gobDesc->realStateMach; xPos = _vm->_goblin->_gobPositions[0].x; @@ -2774,11 +2923,10 @@ void Inter_v1::o1_initGoblin(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Obj _vm->_scenery->updateAnim(layer, 0, gobDesc->animation, 0, gobDesc->xPos, gobDesc->yPos, 0); - gobDesc->yPos = - (yPos * 6 + 6) - (_vm->_scenery->_toRedrawBottom - - _vm->_scenery->_animTop); - gobDesc->xPos = - xPos * 12 - (_vm->_scenery->_toRedrawLeft - _vm->_scenery->_animLeft); + gobDesc->yPos = (yPos * 6 + 6) - + (_vm->_scenery->_toRedrawBottom - _vm->_scenery->_animTop); + gobDesc->xPos = xPos * 12 - + (_vm->_scenery->_toRedrawLeft - _vm->_scenery->_animLeft); } if (gobDesc->state != 10) @@ -2790,28 +2938,28 @@ void Inter_v1::o1_initGoblin(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Obj if (gobDesc->curFrame != 10) return; - objDesc = _vm->_goblin->_objects[_vm->_goblin->_itemIndInPocket]; - objDesc->type = 0; - objDesc->toRedraw = 1; - objDesc->curFrame = 0; + params.objDesc = _vm->_goblin->_objects[_vm->_goblin->_itemIndInPocket]; + params.objDesc->type = 0; + params.objDesc->toRedraw = 1; + params.objDesc->curFrame = 0; - objDesc->order = gobDesc->order; - objDesc->animation = - objDesc->stateMach[objDesc->state][0]->animation; + params.objDesc->order = gobDesc->order; + params.objDesc->animation = + params.objDesc->stateMach[params.objDesc->state][0]->animation; - layer = objDesc->stateMach[objDesc->state][0]->layer; + layer = params.objDesc->stateMach[params.objDesc->state][0]->layer; - _vm->_scenery->updateAnim(layer, 0, objDesc->animation, 0, - objDesc->xPos, objDesc->yPos, 0); + _vm->_scenery->updateAnim(layer, 0, params.objDesc->animation, 0, + params.objDesc->xPos, params.objDesc->yPos, 0); - objDesc->yPos += - (_vm->_goblin->_gobPositions[0].y * 6 + 5) - _vm->_scenery->_toRedrawBottom; + params.objDesc->yPos += (_vm->_goblin->_gobPositions[0].y * 6 + 5) - + _vm->_scenery->_toRedrawBottom; if (gobDesc->curLookDir == 4) { - objDesc->xPos += _vm->_goblin->_gobPositions[0].x * 12 + 14 + params.objDesc->xPos += _vm->_goblin->_gobPositions[0].x * 12 + 14 - (_vm->_scenery->_toRedrawLeft + _vm->_scenery->_toRedrawRight) / 2; } else { - objDesc->xPos += _vm->_goblin->_gobPositions[0].x * 12 + params.objDesc->xPos += _vm->_goblin->_gobPositions[0].x * 12 - (_vm->_scenery->_toRedrawLeft + _vm->_scenery->_toRedrawRight) / 2; } @@ -2821,8 +2969,10 @@ void Inter_v1::o1_initGoblin(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Obj } int16 Inter_v1::loadSound(int16 slot) { - char *dataPtr; + byte *dataPtr; int16 id; + uint32 dataSize; + SoundSource source; if (slot == -1) slot = _vm->_parse->parseValExpr(); @@ -2834,74 +2984,25 @@ int16 Inter_v1::loadSound(int16 slot) { } if (id >= 30000) { - dataPtr = _vm->_game->loadExtData(id, 0, 0); - _vm->_game->_soundFromExt[slot] = 1; - } else { - dataPtr = _vm->_game->loadTotResource(id); - _vm->_game->_soundFromExt[slot] = 0; - } - - _vm->_game->loadSound(slot, dataPtr); - return 0; -} - -void Inter_v1::loadMult(void) { - int16 val; - int16 objIndex; - int16 i; - char *lmultData; + source = SOUND_EXT; - debugC(4, kDebugGameFlow, "Inter_v1::loadMult(): Loading..."); + dataPtr = (byte *) _vm->_game->loadExtData(id, 0, 0, &dataSize); + } else { + int16 totSize; - evalExpr(&objIndex); - evalExpr(&val); - *_vm->_mult->_objects[objIndex].pPosX = val; - evalExpr(&val); - *_vm->_mult->_objects[objIndex].pPosY = val; + source = SOUND_TOT; - lmultData = (char *)_vm->_mult->_objects[objIndex].pAnimData; - for (i = 0; i < 11; i++) { - if ((char)READ_LE_UINT16(_vm->_global->_inter_execPtr) == (char)99) { - evalExpr(&val); - lmultData[i] = val; - } else { - _vm->_global->_inter_execPtr++; - } + dataPtr = (byte *) _vm->_game->loadTotResource(id, &totSize); + dataSize = (uint32) ((int32) totSize); } -} - -void Inter_v1::storeKey(int16 key) { - WRITE_VAR(12, _vm->_util->getTimeKey() - _vm->_game->_startTimeKey); - - storeMouse(); - WRITE_VAR(1, _vm->_snd->_playingSound); - - if (key == 0x4800) - key = 0x0B; - else if (key == 0x5000) - key = 0x0A; - else if (key == 0x4D00) - key = 0x09; - else if (key == 0x4B00) - key = 0x08; - else if (key == 0x011B) - key = 0x1B; - else if ((key & 0xFF) != 0) - key &= 0xFF; - - WRITE_VAR(0, key); - if (key != 0) - _vm->_util->waitKey(); -} - -void Inter_v1::storeMouse(void) { - WRITE_VAR(2, _vm->_global->_inter_mouseX); - WRITE_VAR(3, _vm->_global->_inter_mouseY); - WRITE_VAR(4, _vm->_game->_mouseButtons); + if (dataPtr) + _vm->_game->_soundSamples[slot].load(SOUND_SND, source, + dataPtr, dataSize); + return 0; } -void Inter_v1::animPalette(void) { +void Inter_v1::animPalette() { int16 i; Video::Color col; @@ -2929,4 +3030,127 @@ void Inter_v1::animPalette(void) { _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); } +void Inter_v1::manipulateMap(int16 xPos, int16 yPos, int16 item) { + for (int y = 0; y < _vm->_map->_mapHeight; y++) { + for (int x = 0; x < _vm->_map->_mapWidth; x++) { + if ((_vm->_map->_itemsMap[y][x] & 0xFF) == item) + _vm->_map->_itemsMap[y][x] &= 0xFF00; + else if (((_vm->_map->_itemsMap[y][x] & 0xFF00) >> 8) == item) + _vm->_map->_itemsMap[y][x] &= 0xFF; + } + } + + if (xPos < _vm->_map->_mapWidth - 1) { + if (yPos > 0) { + if (((_vm->_map->_itemsMap[yPos][xPos] & 0xFF00) != 0) || + ((_vm->_map->_itemsMap[yPos - 1][xPos] & 0xFF00) != 0) || + ((_vm->_map->_itemsMap[yPos][xPos + 1] & 0xFF00) != 0) || + ((_vm->_map->_itemsMap[yPos - 1][xPos + 1] & 0xFF00) != 0)) { + + _vm->_map->_itemsMap[yPos][xPos] = + (_vm->_map->_itemsMap[yPos][xPos] & 0xFF00) + item; + + _vm->_map->_itemsMap[yPos - 1][xPos] = + (_vm->_map->_itemsMap[yPos - 1][xPos] & 0xFF00) + item; + + _vm->_map->_itemsMap[yPos][xPos + 1] = + (_vm->_map->_itemsMap[yPos][xPos + 1] & 0xFF00) + item; + + _vm->_map->_itemsMap[yPos - 1][xPos + 1] = + (_vm->_map->_itemsMap[yPos - 1][xPos + 1] & 0xFF00) + item; + + } else { + _vm->_map->_itemsMap[yPos][xPos] = + (_vm->_map->_itemsMap[yPos][xPos] & 0xFF) + (item << 8); + + _vm->_map->_itemsMap[yPos - 1][xPos] = + (_vm->_map->_itemsMap[yPos - 1][xPos] & 0xFF) + (item << 8); + + _vm->_map->_itemsMap[yPos][xPos + 1] = + (_vm->_map->_itemsMap[yPos][xPos + 1] & 0xFF) + (item << 8); + + _vm->_map->_itemsMap[yPos - 1][xPos + 1] = + (_vm->_map->_itemsMap[yPos - 1][xPos + 1] & 0xFF) + (item << 8); + } + } else { + if (((_vm->_map->_itemsMap[yPos][xPos] & 0xFF00) != 0) || + ((_vm->_map->_itemsMap[yPos][xPos + 1] & 0xFF00) != 0)) { + + _vm->_map->_itemsMap[yPos][xPos] = + (_vm->_map->_itemsMap[yPos][xPos] & 0xFF00) + item; + + _vm->_map->_itemsMap[yPos][xPos + 1] = + (_vm->_map->_itemsMap[yPos][xPos + 1] & 0xFF00) + item; + + } else { + _vm->_map->_itemsMap[yPos][xPos] = + (_vm->_map->_itemsMap[yPos][xPos] & 0xFF) + (item << 8); + + _vm->_map->_itemsMap[yPos][xPos + 1] = + (_vm->_map->_itemsMap[yPos][xPos + 1] & 0xFF) + (item << 8); + } + } + } else { + if (yPos > 0) { + if (((_vm->_map->_itemsMap[yPos][xPos] & 0xFF00) != 0) || + ((_vm->_map->_itemsMap[yPos - 1][xPos] & 0xFF00) != 0)) { + + _vm->_map->_itemsMap[yPos][xPos] = + (_vm->_map->_itemsMap[yPos][xPos] & 0xFF00) + item; + + _vm->_map->_itemsMap[yPos - 1][xPos] = + (_vm->_map->_itemsMap[yPos - 1][xPos] & 0xFF00) + item; + + } else { + _vm->_map->_itemsMap[yPos][xPos] = + (_vm->_map->_itemsMap[yPos][xPos] & 0xFF) + (item << 8); + + _vm->_map->_itemsMap[yPos - 1][xPos] = + (_vm->_map->_itemsMap[yPos - 1][xPos] & 0xFF) + (item << 8); + } + } else { + if ((_vm->_map->_itemsMap[yPos][xPos] & 0xFF00) != 0) { + _vm->_map->_itemsMap[yPos][xPos] = + (_vm->_map->_itemsMap[yPos][xPos] & 0xFF00) + item; + } else { + _vm->_map->_itemsMap[yPos][xPos] = + (_vm->_map->_itemsMap[yPos][xPos] & 0xFF) + (item << 8); + } + } + } + + if ((item < 0) || (item >= 20)) + return; + + if ((xPos > 1) && (_vm->_map->getPass(xPos - 2, yPos) == 1)) { + _vm->_map->_itemPoses[item].x = xPos - 2; + _vm->_map->_itemPoses[item].y = yPos; + _vm->_map->_itemPoses[item].orient = 4; + return; + } + + if ((xPos < _vm->_map->_mapWidth - 2) && + (_vm->_map->getPass(xPos + 2, yPos) == 1)) { + _vm->_map->_itemPoses[item].x = xPos + 2; + _vm->_map->_itemPoses[item].y = yPos; + _vm->_map->_itemPoses[item].orient = 0; + return; + } + + if ((xPos < _vm->_map->_mapWidth - 1) && + (_vm->_map->getPass(xPos + 1, yPos) == 1)) { + _vm->_map->_itemPoses[item].x = xPos + 1; + _vm->_map->_itemPoses[item].y = yPos; + _vm->_map->_itemPoses[item].orient = 0; + return; + } + + if ((xPos > 0) && (_vm->_map->getPass(xPos - 1, yPos) == 1)) { + _vm->_map->_itemPoses[item].x = xPos - 1; + _vm->_map->_itemPoses[item].y = yPos; + _vm->_map->_itemPoses[item].orient = 4; + return; + } +} + } // End of namespace Gob diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp index 8cb1c76c06..96fab8d675 100644 --- a/engines/gob/inter_v2.cpp +++ b/engines/gob/inter_v2.cpp @@ -23,22 +23,26 @@ #include "common/stdafx.h" #include "common/endian.h" +#include "sound/mixer.h" +#include "sound/mods/infogrames.h" #include "gob/gob.h" -#include "gob/global.h" #include "gob/inter.h" +#include "gob/global.h" #include "gob/util.h" -#include "gob/scenery.h" -#include "gob/parse.h" -#include "gob/game.h" +#include "gob/dataio.h" +#include "gob/music.h" +#include "gob/cdrom.h" #include "gob/draw.h" -#include "gob/mult.h" +#include "gob/game.h" #include "gob/goblin.h" -#include "gob/cdrom.h" -#include "gob/palanim.h" -#include "gob/anim.h" -#include "gob/music.h" +#include "gob/imd.h" #include "gob/map.h" +#include "gob/mult.h" +#include "gob/parse.h" +#include "gob/scenery.h" +#include "gob/sound.h" +#include "gob/video.h" namespace Gob { @@ -122,18 +126,18 @@ Inter_v2::Inter_v2(GobEngine *vm) : Inter_v1(vm) { setupOpcodes(); } -void Inter_v2::setupOpcodes(void) { +void Inter_v2::setupOpcodes() { static const OpcodeDrawEntryV2 opcodesDraw[256] = { /* 00 */ OPCODE(o1_loadMult), OPCODE(o2_playMult), - OPCODE(o1_freeMult), + OPCODE(o1_freeMultKeys), {NULL, ""}, /* 04 */ {NULL, ""}, {NULL, ""}, {NULL, ""}, - OPCODE(o2_initCursor), + OPCODE(o1_initCursor), /* 08 */ OPCODE(o1_initCursorAnim), OPCODE(o1_clearCursorAnim), @@ -151,12 +155,12 @@ void Inter_v2::setupOpcodes(void) { OPCODE(o2_multSub), /* 14 */ OPCODE(o2_initMult), - OPCODE(o1_multFreeMult), + OPCODE(o1_freeMult), OPCODE(o1_animate), - OPCODE(o1_multLoadMult), + OPCODE(o2_loadMultObject), /* 18 */ - OPCODE(o1_storeParams), - OPCODE(o2_getObjAnimSize), + OPCODE(o1_getAnimLayerInfo), + OPCODE(o1_getObjAnimSize), OPCODE(o1_loadStatic), OPCODE(o1_freeStatic), /* 1C */ @@ -166,7 +170,7 @@ void Inter_v2::setupOpcodes(void) { {NULL, ""}, /* 20 */ OPCODE(o2_playCDTrack), - OPCODE(o2_drawStub), + OPCODE(o2_waitCDTrackEnd), OPCODE(o2_stopCD), OPCODE(o2_readLIC), /* 24 */ @@ -230,8 +234,8 @@ void Inter_v2::setupOpcodes(void) { OPCODE(o2_moveGoblin), OPCODE(o2_writeGoblinPos), /* 54 */ - OPCODE(o2_stub0x54), - OPCODE(o2_stub0x55), + OPCODE(o2_stopGoblin), + OPCODE(o2_setGoblinState), OPCODE(o2_placeGoblin), {NULL, ""}, /* 58 */ @@ -290,12 +294,12 @@ void Inter_v2::setupOpcodes(void) { OPCODE(o2_setScrollOffset), OPCODE(o2_playImd), /* 84 */ - OPCODE(o2_drawStub), - OPCODE(o2_stub0x85), - OPCODE(o2_drawStub), - OPCODE(o2_drawStub), + OPCODE(o2_getImdInfo), + OPCODE(o2_openItk), + OPCODE(o2_closeItk), + OPCODE(o2_setImdFrontSurf), /* 88 */ - OPCODE(o2_drawStub), + OPCODE(o2_resetImdFrontSurf), {NULL, ""}, {NULL, ""}, {NULL, ""}, @@ -450,15 +454,15 @@ void Inter_v2::setupOpcodes(void) { /* 00 */ OPCODE(o1_callSub), OPCODE(o1_callSub), - OPCODE(o1_drawPrintText), + OPCODE(o1_printTotText), OPCODE(o1_loadCursor), /* 04 */ {NULL, ""}, - OPCODE(o1_call), + OPCODE(o1_switch), OPCODE(o1_repeatUntil), OPCODE(o1_whileDo), /* 08 */ - OPCODE(o1_callBool), + OPCODE(o1_if), OPCODE(o2_evaluateStore), OPCODE(o1_loadSpriteToPos), {NULL, ""}, @@ -470,8 +474,8 @@ void Inter_v2::setupOpcodes(void) { /* 10 */ {NULL, ""}, OPCODE(o2_printText), - OPCODE(o2_loadTot), - OPCODE(o2_palLoad), + OPCODE(o1_loadTot), + OPCODE(o1_palLoad), /* 14 */ OPCODE(o1_keyFunc), OPCODE(o1_capturePush), @@ -496,7 +500,7 @@ void Inter_v2::setupOpcodes(void) { OPCODE(o1_putPixel), OPCODE(o2_goblinFunc), OPCODE(o2_createSprite), - OPCODE(o2_freeSprite), + OPCODE(o1_freeSprite), /* 28 */ {NULL, ""}, {NULL, ""}, @@ -518,7 +522,7 @@ void Inter_v2::setupOpcodes(void) { OPCODE(o1_invalidate), OPCODE(o1_setBackDelta), /* 38 */ - OPCODE(o2_playSound), + OPCODE(o1_playSound), OPCODE(o2_stopSound), OPCODE(o2_loadSound), OPCODE(o1_freeSoundSlot), @@ -647,7 +651,8 @@ void Inter_v2::setupOpcodes(void) { } void Inter_v2::executeDrawOpcode(byte i) { - debugC(1, kDebugDrawOp, "opcodeDraw %d [0x%x] (%s)", i, i, getOpcodeDrawDesc(i)); + debugC(1, kDebugDrawOp, "opcodeDraw %d [0x%X] (%s)", + i, i, getOpcodeDrawDesc(i)); OpcodeDrawProcV2 op = _opcodesDrawV2[i].proc; @@ -657,8 +662,9 @@ void Inter_v2::executeDrawOpcode(byte i) { (this->*op) (); } -bool Inter_v2::executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, int16 &retFlag) { - debugC(1, kDebugFuncOp, "opcodeFunc %d.%d [0x%x.0x%x] (%s)", i, j, i, j, getOpcodeFuncDesc(i, j)); +bool Inter_v2::executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms) { + debugC(1, kDebugFuncOp, "opcodeFunc %d.%d [0x%X.0x%X] (%s)", + i, j, i, j, getOpcodeFuncDesc(i, j)); if ((i > 4) || (j > 15)) { warning("unimplemented opcodeFunc: %d.%d", i, j); @@ -670,13 +676,14 @@ bool Inter_v2::executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, if (op == NULL) warning("unimplemented opcodeFunc: %d.%d", i, j); else - return (this->*op) (cmdCount, counter, retFlag); + return (this->*op) (params); return false; } -void Inter_v2::executeGoblinOpcode(int i, int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - debugC(1, kDebugGobOp, "opcodeGoblin %d [0x%x] (%s)", i, i, getOpcodeGoblinDesc(i)); +void Inter_v2::executeGoblinOpcode(int i, OpGobParams ¶ms) { + debugC(1, kDebugGobOp, "opcodeGoblin %d [0x%X] (%s)", + i, i, getOpcodeGoblinDesc(i)); OpcodeGoblinProcV2 op = NULL; @@ -694,7 +701,7 @@ void Inter_v2::executeGoblinOpcode(int i, int16 &extraData, int32 *retVarPtr, Go _vm->_global->_inter_execPtr += val << 1; } else - (this->*op) (extraData, retVarPtr, objDesc); + (this->*op) (params); } const char *Inter_v2::getOpcodeDrawDesc(byte i) { @@ -716,7 +723,6 @@ const char *Inter_v2::getOpcodeGoblinDesc(int i) { } void Inter_v2::checkSwitchTable(char **ppExec) { - int i; byte cmd; int16 len; int32 value; @@ -750,14 +756,15 @@ void Inter_v2::checkSwitchTable(char **ppExec) { len = (int8) *_vm->_global->_inter_execPtr++; while (len != -5) { - for (i = 0; i < len; i++) { + for (int i = 0; i < len; i++) { cmd = *_vm->_global->_inter_execPtr; - switch(cmd) { + switch (cmd) { case 19: _vm->_global->_inter_execPtr++; if (!found && - (value == (int32) (READ_LE_UINT32(_vm->_global->_inter_execPtr)))) + (value == + (int32) (READ_LE_UINT32(_vm->_global->_inter_execPtr)))) found = true; _vm->_global->_inter_execPtr += 5; break; @@ -765,7 +772,8 @@ void Inter_v2::checkSwitchTable(char **ppExec) { case 20: _vm->_global->_inter_execPtr++; if (!found && - (value == (int16) (READ_LE_UINT16(_vm->_global->_inter_execPtr)))) + (value == + (int16) (READ_LE_UINT16(_vm->_global->_inter_execPtr)))) found = true; _vm->_global->_inter_execPtr += 3; break; @@ -791,7 +799,8 @@ void Inter_v2::checkSwitchTable(char **ppExec) { if (found && (*ppExec == 0)) *ppExec = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; len = (int8) *_vm->_global->_inter_execPtr++; } @@ -802,241 +811,364 @@ void Inter_v2::checkSwitchTable(char **ppExec) { if (*ppExec == 0) *ppExec = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + _vm->_global->_inter_execPtr += + READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; } -void Inter_v2::o2_stub0x54(void) { - int16 index = _vm->_parse->parseValExpr(); +void Inter_v2::o2_playMult() { + int16 checkEscape; - _vm->_mult->_objects[index].pAnimData->pathExistence = 4; + checkEscape = load16(); + + _vm->_mult->setMultData(checkEscape >> 1); + _vm->_mult->playMult(VAR(57), -1, checkEscape & 0x1, 0); } -void Inter_v2::o2_stub0x55(void) { - int16 index; - int16 state; - int16 f16; - int16 layer; - int16 animation; - int16 deltaX; - int16 deltaY; - int16 deltaHeight; - int16 deltaWidth; - Mult::Mult_Object *obj; - Mult::Mult_AnimData *objAnim; +void Inter_v2::o2_setRenderFlags() { + int16 expr; - index = _vm->_parse->parseValExpr(); - state = _vm->_parse->parseValExpr(); - f16 = _vm->_parse->parseValExpr(); + expr = _vm->_parse->parseValExpr(); + + if (expr & 0x8000) { + _vm->_draw->_renderFlags |= expr & 0x3FFF; + } + else { + if (expr & 0x4000) + _vm->_draw->_renderFlags &= expr & 0x3FFF; + else + _vm->_draw->_renderFlags = expr; + } +} - obj = &_vm->_mult->_objects[index]; - objAnim = obj->pAnimData; +void Inter_v2::o2_multSub() { + _vm->_mult->multSub(_vm->_parse->parseValExpr()); +} - objAnim->field_16 = f16; - switch (f16) { - case 0: - if (obj->goblinStates[state] != 0) { - objAnim->frame = 0; - layer = obj->goblinStates[state][0].layer; - animation = obj->goblinStates[state][0].animation; - objAnim->state = state; - objAnim->layer = layer; - objAnim->animation = animation; - *obj->pPosX = _vm->_scenery->_animations[animation].layers[layer].posX; - *obj->pPosY = _vm->_scenery->_animations[animation].layers[layer].posY; - objAnim->isPaused = 0; - objAnim->isStatic = 0; - objAnim->newCycle = _vm->_scenery->_animations[animation].layers[layer].framesCount; - } - break; +void Inter_v2::o2_initMult() { + int16 oldAnimHeight; + int16 oldAnimWidth; + int16 oldObjCount; + int16 posXVar; + int16 posYVar; + int16 animDataVar; - case 1: - case 4: - case 6: - if (obj->goblinStates[state] != 0) { - layer = obj->goblinStates[objAnim->state][0].layer; - animation = obj->goblinStates[objAnim->state][0].animation; - _vm->_scenery->updateAnim(layer, 0, animation, 0, *obj->pPosX, *obj->pPosY, 0); - deltaHeight = _vm->_scenery->_animBottom - _vm->_scenery->_animTop; - deltaWidth = _vm->_scenery->_animRight - _vm->_scenery->_animLeft; - deltaX = _vm->_scenery->_animations[objAnim->animation].layers[objAnim->layer].animDeltaX; - deltaY = _vm->_scenery->_animations[objAnim->animation].layers[objAnim->layer].animDeltaY; - layer = obj->goblinStates[state][0].layer; - animation = obj->goblinStates[state][0].animation; - objAnim->state = state; - objAnim->layer = layer; - objAnim->animation = animation; - objAnim->frame = 0; - objAnim->isPaused = 0; - objAnim->isStatic = 0; - objAnim->newCycle = _vm->_scenery->_animations[animation].layers[layer].framesCount; - _vm->_scenery->updateAnim(layer, 0, animation, 0, *obj->pPosX, *obj->pPosY, 0); - deltaHeight -= _vm->_scenery->_animBottom - _vm->_scenery->_animTop; - deltaWidth -= _vm->_scenery->_animRight - _vm->_scenery->_animLeft; - *obj->pPosX += deltaWidth + deltaX; - *obj->pPosY += deltaHeight + deltaY; + oldAnimWidth = _vm->_mult->_animWidth; + oldAnimHeight = _vm->_mult->_animHeight; + oldObjCount = _vm->_mult->_objCount; + + _vm->_mult->_animLeft = load16(); + _vm->_mult->_animTop = load16(); + _vm->_mult->_animWidth = load16(); + _vm->_mult->_animHeight = load16(); + _vm->_mult->_objCount = load16(); + posXVar = _vm->_parse->parseVarIndex(); + posYVar = _vm->_parse->parseVarIndex(); + animDataVar = _vm->_parse->parseVarIndex(); + + if (_vm->_mult->_objects && (oldObjCount != _vm->_mult->_objCount)) { + warning("Initializing new objects without having " + "cleaned up the old ones at first"); + delete[] _vm->_mult->_objects; + delete[] _vm->_mult->_renderObjs; + delete[] _vm->_mult->_orderArray; + _vm->_mult->_objects = 0; + _vm->_mult->_renderObjs = 0; + _vm->_mult->_orderArray = 0; + } + + if (_vm->_mult->_objects == 0) { + _vm->_mult->_renderObjs = new Mult::Mult_Object*[_vm->_mult->_objCount]; + memset(_vm->_mult->_renderObjs, 0, + _vm->_mult->_objCount * sizeof(Mult::Mult_Object*)); + + if (_terminate) + return; + + _vm->_mult->_orderArray = new int8[_vm->_mult->_objCount]; + memset(_vm->_mult->_orderArray, 0, _vm->_mult->_objCount * sizeof(int8)); + _vm->_mult->_objects = new Mult::Mult_Object[_vm->_mult->_objCount]; + memset(_vm->_mult->_objects, 0, + _vm->_mult->_objCount * sizeof(Mult::Mult_Object)); + + for (int i = 0; i < _vm->_mult->_objCount; i++) { + _vm->_mult->_objects[i].pPosX = + (int32 *)(_vm->_global->_inter_variables + + i * 4 + (posXVar / 4) * 4); + _vm->_mult->_objects[i].pPosY = + (int32 *)(_vm->_global->_inter_variables + + i * 4 + (posYVar / 4) * 4); + + _vm->_mult->_objects[i].pAnimData = + (Mult::Mult_AnimData *) (_vm->_global->_inter_variables + + animDataVar + i * 4 * _vm->_global->_inter_animDataSize); + memset(_vm->_global->_inter_variablesSizes + + i * 4 * _vm->_global->_inter_animDataSize, 0, + _vm->_global->_inter_animDataSize); + + _vm->_mult->_objects[i].pAnimData->isStatic = 1; + _vm->_mult->_objects[i].tick = 0; + _vm->_mult->_objects[i].lastLeft = -1; + _vm->_mult->_objects[i].lastRight = -1; + _vm->_mult->_objects[i].lastTop = -1; + _vm->_mult->_objects[i].lastBottom = -1; + _vm->_mult->_objects[i].goblinX = 1; + _vm->_mult->_objects[i].goblinY = 1; } - break; + } - case 11: - if (obj->goblinStates[state] != 0) { - layer = obj->goblinStates[state][0].layer; - animation = obj->goblinStates[state][0].animation; - objAnim->state = state; - objAnim->layer = layer; - objAnim->animation = animation; - objAnim->frame = 0; - objAnim->isPaused = 0; - objAnim->isStatic = 0; - objAnim->newCycle = _vm->_scenery->_animations[animation].layers[layer].framesCount; - _vm->_scenery->updateAnim(layer, 0, animation, 0, *obj->pPosX, *obj->pPosY, 0); - if (_vm->_map->_bigTiles) - *obj->pPosY = ((obj->goblinY + 1) * _vm->_map->_tilesHeight) - - (_vm->_scenery->_animBottom - _vm->_scenery->_animTop) - - ((obj->goblinY + 1) / 2); - else - *obj->pPosY = ((obj->goblinY + 1) * _vm->_map->_tilesHeight) - - (_vm->_scenery->_animBottom - _vm->_scenery->_animTop); - *obj->pPosX = obj->goblinX * _vm->_map->_tilesWidth; + if (_vm->_mult->_animSurf && + ((oldAnimWidth != _vm->_mult->_animWidth) || + (oldAnimHeight != _vm->_mult->_animHeight))) { + _vm->_draw->freeSprite(22); + _vm->_mult->_animSurf = 0; + } + + _vm->_draw->adjustCoords(0, + &_vm->_mult->_animWidth, &_vm->_mult->_animHeight); + if (_vm->_mult->_animSurf == 0) { + _vm->_draw->initSpriteSurf(22, _vm->_mult->_animWidth, + _vm->_mult->_animHeight, 0); + _vm->_mult->_animSurf = _vm->_draw->_spritesArray[22]; + if (_terminate) + return; + } + + _vm->_draw->adjustCoords(1, + &_vm->_mult->_animWidth, &_vm->_mult->_animHeight); + _vm->_draw->_sourceSurface = 21; + _vm->_draw->_destSurface = 22; + _vm->_draw->_spriteLeft = _vm->_mult->_animLeft; + _vm->_draw->_spriteTop = _vm->_mult->_animTop; + _vm->_draw->_spriteRight = _vm->_mult->_animWidth; + _vm->_draw->_spriteBottom = _vm->_mult->_animHeight; + _vm->_draw->_destSpriteX = 0; + _vm->_draw->_destSpriteY = 0; + _vm->_draw->spriteOperation(0); + + debugC(4, kDebugGraphics, "o2_initMult: x = %d, y = %d, w = %d, h = %d", + _vm->_mult->_animLeft, _vm->_mult->_animTop, + _vm->_mult->_animWidth, _vm->_mult->_animHeight); + debugC(4, kDebugGraphics, " _vm->_mult->_objCount = %d, " + "animation data size = %d", _vm->_mult->_objCount, + _vm->_global->_inter_animDataSize); +} + +void Inter_v2::o2_loadMultObject() { + int16 val; + int16 objIndex; + int16 animation; + int16 layer; + char *multData; + + objIndex = _vm->_parse->parseValExpr(); + val = _vm->_parse->parseValExpr(); + *_vm->_mult->_objects[objIndex].pPosX = val; + val = _vm->_parse->parseValExpr(); + *_vm->_mult->_objects[objIndex].pPosY = val; + + debugC(4, kDebugGameFlow, "Loading mult object %d", objIndex); + + multData = (char *) _vm->_mult->_objects[objIndex].pAnimData; + for (int i = 0; i < 11; i++) { + if (*_vm->_global->_inter_execPtr != 99) + multData[i] = _vm->_parse->parseValExpr(); + else + _vm->_global->_inter_execPtr++; + } + + if (_vm->_goblin->_gobsCount < 0) + return; + + Mult::Mult_Object &obj = _vm->_mult->_objects[objIndex]; + Mult::Mult_AnimData &objAnim = *(obj.pAnimData); + if (objAnim.animType == 100) { + + val = *(obj.pPosX) % 256; + obj.destX = val; + obj.gobDestX = val; + obj.goblinX = val; + + val = *(obj.pPosY) % 256; + obj.destY = val; + obj.gobDestY = val; + obj.goblinY = val; + + *(obj.pPosX) *= _vm->_map->_tilesWidth; + + layer = objAnim.layer; + animation = obj.goblinStates[layer][0].animation; + objAnim.framesLeft = objAnim.maxFrame; + objAnim.nextState = -1; + objAnim.newState = -1; + objAnim.pathExistence = 0; + objAnim.isBusy = 0; + objAnim.state = layer; + objAnim.layer = obj.goblinStates[objAnim.state][0].layer; + objAnim.animation = animation; + _vm->_scenery->updateAnim(layer, 0, animation, 0, + *(obj.pPosX), *(obj.pPosY), 0); + + if (!_vm->_map->_bigTiles) + *(obj.pPosY) = (obj.goblinY + 1) * _vm->_map->_tilesHeight + - (_vm->_scenery->_animBottom - _vm->_scenery->_animTop); + else + *(obj.pPosY) = ((obj.goblinY + 1) * _vm->_map->_tilesHeight) - + (_vm->_scenery->_animBottom - _vm->_scenery->_animTop) - + ((obj.goblinY + 1) / 2); + *(obj.pPosX) = obj.goblinX * _vm->_map->_tilesWidth; + + } else if (objAnim.animType == 101) { + + layer = objAnim.layer; + animation = obj.goblinStates[layer][0].animation; + objAnim.nextState = -1; + objAnim.newState = -1; + objAnim.state = layer; + objAnim.layer = obj.goblinStates[objAnim.state][0].layer; + objAnim.animation = animation; + + if ((*(obj.pPosX) == 1000) && (*(obj.pPosY) == 1000)) { + Scenery::AnimLayer *animLayer = + _vm->_scenery->getAnimLayer(animation, objAnim.layer); + + *(obj.pPosX) = animLayer->posX; + *(obj.pPosY) = animLayer->posY; } - break; + _vm->_scenery->updateAnim(layer, 0, animation, 0, + *(obj.pPosX), *(obj.pPosY), 0); } } -void Inter_v2::o2_stub0x85(void) { - char dest[32]; +void Inter_v2::o2_renderStatic() { + int16 layer; + int16 index; - evalExpr(0); - strcpy(dest, _vm->_global->_inter_resStr); - strcat(dest, ".ITK"); + index = _vm->_parse->parseValExpr(); + layer = _vm->_parse->parseValExpr(); + _vm->_scenery->renderStatic(index, layer); +} - warning("STUB: Gob2 drawOperation 0x85 (\"%s\")", dest); - _vm->_dataio->openDataFile(dest); +void Inter_v2::o2_loadCurLayer() { + _vm->_scenery->_curStatic = _vm->_parse->parseValExpr(); + _vm->_scenery->_curStaticLayer = _vm->_parse->parseValExpr(); } -int16 Inter_v2::loadSound(int16 search) { - int16 id; - int16 slot; - uint32 i; - bool isADL; - char sndfile[14]; - char *extData; - char *dataPtr; - Snd::SoundDesc *soundDesc; +void Inter_v2::o2_playCDTrack() { + if (!(_vm->_draw->_renderFlags & RENDERFLAG_NOBLITINVALIDATED)) + _vm->_draw->blitInvalidated(); - memset(sndfile, 0, 14 * sizeof(char)); + evalExpr(0); + _vm->_cdrom->startTrack(_vm->_global->_inter_resStr); +} - isADL = false; - if (search == 0) { - slot = _vm->_parse->parseValExpr(); - if (slot < 0) { - isADL = true; - slot = -slot; - } - id = load16(); - } else { - id = load16(); +void Inter_v2::o2_waitCDTrackEnd() { + while (_vm->_cdrom->getTrackPos() >= 0) + _vm->_util->longDelay(1); +} - for (slot = 0; slot < 60; slot++) - if ((_vm->_game->_soundSamples[slot] != 0) && (_vm->_game->_soundIds[slot] == id)) - return slot | 0x8000; +void Inter_v2::o2_stopCD() { + _vm->_cdrom->stopPlaying(); +} - for (slot = 59; slot >= 0; slot--) - if (_vm->_game->_soundSamples[slot] == 0) break; - } +void Inter_v2::o2_readLIC() { + char path[40]; - if (_vm->_game->_soundSamples[slot] != 0) - _vm->_game->freeSoundSlot(slot); + evalExpr(0); + strcpy(path, _vm->_global->_inter_resStr); + strcat(path, ".LIC"); - _vm->_game->_soundIds[slot] = id; - _vm->_game->_soundADL[slot] = isADL; + _vm->_cdrom->readLIC(path); +} - if (id == -1) { - strcpy(sndfile, _vm->_global->_inter_execPtr); - _vm->_global->_inter_execPtr += 9; - if (!isADL) { - strcat(sndfile, ".SND"); - _vm->_game->_soundSamples[slot] = _vm->_game->loadSND(sndfile, 3); - } else { - strcat(sndfile, ".ADL"); - dataPtr = _vm->_dataio->getData(sndfile); - if (dataPtr == 0) - return slot; +void Inter_v2::o2_freeLIC() { + _vm->_cdrom->freeLICbuffer(); +} - _vm->_game->_soundSamples[slot] = new Snd::SoundDesc; - _vm->_game->_soundSamples[slot]->data = dataPtr; - } - _vm->_game->_soundTypes[slot] = 2; +void Inter_v2::o2_getCDTrackPos() { + int16 varPos; + int16 varName; + + _vm->_util->longDelay(1); + + varPos = _vm->_parse->parseVarIndex(); + varName = _vm->_parse->parseVarIndex(); + + WRITE_VAR_OFFSET(varPos, _vm->_cdrom->getTrackPos()); + WRITE_VARO_STR(varName, _vm->_cdrom->getCurTrack()); +} + +void Inter_v2::o2_loadFontToSprite() { + int16 i = load16(); + + _vm->_draw->_fontToSprite[i].sprite = *_vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr += 2; + _vm->_draw->_fontToSprite[i].base = *_vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr += 2; + _vm->_draw->_fontToSprite[i].width = *_vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr += 2; + _vm->_draw->_fontToSprite[i].height = *_vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr += 2; +} + +void Inter_v2::o2_totSub() { + char totFile[14]; + byte length; + int flags; + int i; + + length = *_vm->_global->_inter_execPtr++; + if ((length & 0x7F) > 13) + error("Length in o2_totSub is greater than 13 (%d)", length); + + if (length & 0x80) { + evalExpr(0); + strcpy(totFile, _vm->_global->_inter_resStr); } else { - if (id >= 30000) { - if (!isADL && (_vm->_game->_totFileData[0x29] >= 51)) { // loc_9763 - if (_terminate != 0) - return slot; - soundDesc = new Snd::SoundDesc; - extData = _vm->_game->loadExtData(id, 0, 0); - if (extData == 0) { - delete soundDesc; - return slot; - } - soundDesc->data = extData + 6; - soundDesc->frequency = MAX((extData[4] << 8) + extData[5], 4700); - soundDesc->size = (extData[1] << 16) + (extData[2] << 8) + extData[3]; - soundDesc->flag = 0; - soundDesc->frequency = -soundDesc->frequency; - for (i = 0, dataPtr = soundDesc->data; i < soundDesc->size; i++, dataPtr++) - *dataPtr ^= 0x80; - _vm->_game->_soundFromExt[slot] = 1; - _vm->_game->_soundTypes[slot] = 4; - _vm->_game->_soundSamples[slot] = soundDesc; - } else { - uint32 dataSize; - - extData = _vm->_game->loadExtData(id, 0, 0, &dataSize); - if (extData == 0) - return slot; - - _vm->_game->_soundFromExt[slot] = 1; - _vm->_game->_soundTypes[slot] = 1; - if (isADL) { - _vm->_game->_soundSamples[slot] = new Snd::SoundDesc; - _vm->_game->_soundSamples[slot]->data = extData; - } else - _vm->_game->loadSound(slot, extData, dataSize); - } - } else { - int16 dataSize; - - extData = _vm->_game->loadTotResource(id, &dataSize); - if (isADL) { - _vm->_game->_soundSamples[slot] = new Snd::SoundDesc; - _vm->_game->_soundSamples[slot]->data = extData; - } else - _vm->_game->loadSound(slot, extData, dataSize); - } + for (i = 0; i < length; i++) + totFile[i] = *_vm->_global->_inter_execPtr++; + totFile[i] = 0; } - if (isADL) - _vm->_game->_soundTypes[slot] |= 8; + // WORKAROUND: There is a race condition in the script when opening the notepad + if (!scumm_stricmp(totFile, "edit")) + _vm->_util->forceMouseUp(); + + flags = (byte) *_vm->_global->_inter_execPtr++; + _vm->_game->totSub(flags, totFile); +} - return slot; +void Inter_v2::o2_switchTotSub() { + int16 index; + int16 skipPlay; + + index = load16(); + skipPlay = load16(); + + _vm->_game->switchTotSub(index, skipPlay); } -void Inter_v2::o2_copyVars(void) { +void Inter_v2::o2_copyVars() { byte count; int16 varOff; - int i; count = *_vm->_global->_inter_execPtr++; - for (i = 0; i < count; i++) { - if ((*_vm->_global->_inter_execPtr == 25) || (*_vm->_global->_inter_execPtr == 28)) { + for (int i = 0; i < count; i++, _pastePos++) { + if ((*_vm->_global->_inter_execPtr == 25) || + (*_vm->_global->_inter_execPtr == 28)) { + varOff = _vm->_parse->parseVarIndex(); _vm->_global->_inter_execPtr++; + memcpy(_pasteBuf + _pastePos, _vm->_global->_inter_variables + varOff, _vm->_global->_inter_animDataSize * 4); - memcpy(_pasteSizeBuf + _pastePos, _vm->_global->_inter_variablesSizes + varOff, + memcpy(_pasteSizeBuf + _pastePos, + _vm->_global->_inter_variablesSizes + varOff, _vm->_global->_inter_animDataSize * 4); + _pastePos += _vm->_global->_inter_animDataSize * 4; _pasteBuf[_pastePos] = _vm->_global->_inter_animDataSize * 4; _pasteSizeBuf[_pastePos] = _vm->_global->_inter_animDataSize * 4; + } else { if (evalExpr(&varOff) == 20) _vm->_global->_inter_resVal = 0; @@ -1046,552 +1178,393 @@ void Inter_v2::o2_copyVars(void) { _pasteBuf[_pastePos] = 4; _pasteSizeBuf[_pastePos] = 4; } - _pastePos++; } } -void Inter_v2::o2_pasteVars(void) { +void Inter_v2::o2_pasteVars() { byte count; int16 varOff; int16 sizeV; int16 sizeS; - int i; count = *_vm->_global->_inter_execPtr++; - for (i = 0; i < count; i++) { + for (int i = 0; i < count; i++) { varOff = _vm->_parse->parseVarIndex(); sizeV = _pasteBuf[--_pastePos]; sizeS = _pasteSizeBuf[_pastePos]; assert(sizeV == sizeS); + _pastePos -= sizeV; memcpy(_vm->_global->_inter_variables + varOff, _pasteBuf + _pastePos, sizeV); memcpy(_vm->_global->_inter_variablesSizes + varOff, _pasteSizeBuf + _pastePos, sizeS); } } -void Inter_v2::o2_loadFontToSprite(void) { - int16 i = load16(); - - _vm->_draw->_fontToSprite[i].sprite = *_vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += 2; - _vm->_draw->_fontToSprite[i].base = *_vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += 2; - _vm->_draw->_fontToSprite[i].width = *_vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += 2; - _vm->_draw->_fontToSprite[i].height = *_vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += 2; -} - -void Inter_v2::o2_loadMapObjects(void) { +void Inter_v2::o2_loadMapObjects() { _vm->_map->loadMapObjects(0); } -void Inter_v2::o2_freeGoblins(void) { +void Inter_v2::o2_freeGoblins() { _vm->_goblin->freeObjects(); } -void Inter_v2::o2_placeGoblin(void) { - int16 index; - int16 x; - int16 y; - int16 state; - - index = _vm->_parse->parseValExpr(); - x = _vm->_parse->parseValExpr(); - y = _vm->_parse->parseValExpr(); - state = _vm->_parse->parseValExpr(); - - _vm->_goblin->placeObject(0, 0, index, x, y, state); -} - -void Inter_v2::o2_moveGoblin(void) { - Mult::Mult_Object *obj; - Mult::Mult_AnimData *objAnim; - int16 destX; - int16 destY; +void Inter_v2::o2_moveGoblin() { + int16 destX, destY; int16 index; - int16 mouseX; - int16 mouseY; - int16 gobDestX; - int16 gobDestY; - int16 mapWidth; - int16 mapHeight; - int16 di; - int16 si; - int16 var_1E; - int16 var_20; - int i; destX = _vm->_parse->parseValExpr(); destY = _vm->_parse->parseValExpr(); index = _vm->_parse->parseValExpr(); - - obj = &_vm->_mult->_objects[index]; - objAnim = obj->pAnimData; - - obj->gobDestX = destX; - obj->gobDestY = destY; - objAnim->field_13 = destX; - objAnim->field_14 = destY; - if (objAnim->isBusy != 0) { - if ((destX == -1) && (destY == -1)) { - mouseX = _vm->_global->_inter_mouseX; - mouseY = _vm->_global->_inter_mouseY; - if (_vm->_map->_bigTiles) - mouseY += ((_vm->_global->_inter_mouseY / _vm->_map->_tilesHeight) + 1) / 2; - obj->gobDestX = mouseX / _vm->_map->_tilesWidth; - obj->gobDestY = mouseY / _vm->_map->_tilesHeight; - gobDestX = obj->gobDestX; - gobDestY = obj->gobDestY; - if (_vm->_map->getPass(obj->gobDestX, obj->gobDestY) == 0) { - mapWidth = _vm->_map->_screenWidth / _vm->_map->_tilesWidth; - mapHeight = 200 / _vm->_map->_tilesHeight; - var_20 = 0; - di = -1; - si = -1; - - for (i = 1; i <= gobDestX; i++) - if (_vm->_map->getPass(gobDestX - i, gobDestY) != 0) - break; - if (i <= gobDestX) - di = ((i - 1) * _vm->_map->_tilesWidth) + (mouseX % _vm->_map->_tilesWidth) + 1; - var_1E = i; - - for (i = 1; (gobDestX + i) < mapWidth; i++) - if (_vm->_map->getPass(gobDestX + i, gobDestY) != 0) - break; - if ((gobDestX + i) < mapWidth) - si = (i * _vm->_map->_tilesWidth) - (mouseX % _vm->_map->_tilesWidth); - - if ((si != -1) && ((di == -1) || (di > si))) { - di = si; - var_20 = 1; - var_1E = i; - } - si = -1; - - for (i = 1; (gobDestY + i) < mapHeight; i++) - if (_vm->_map->getPass(gobDestX, gobDestY + i) != 0) - break; - if ((gobDestY + i) < mapHeight) - si = (i * _vm->_map->_tilesHeight) - (mouseY % _vm->_map->_tilesHeight); - - if ((si != -1) && ((di == -1) || (di > si))) { - di = si; - var_20 = 2; - var_1E = i; - } - si = -1; - - for (i = 1; i <= gobDestY; i++) - if (_vm->_map->getPass(gobDestX, gobDestY - i) != 0) - break; - if (i <= gobDestY) - si = ((i - 1) * _vm->_map->_tilesHeight) + (mouseY % _vm->_map->_tilesHeight) + 1; - - if ((si != -1) && ((di == -1) || (di > si))) { - var_20 = 3; - var_1E = i; - } - - if (var_20 == 0) - gobDestX -= var_1E; - else if (var_20 == 1) - gobDestX += var_1E; - else if (var_20 == 2) - gobDestY += var_1E; - else if (var_20 == 3) - gobDestY -= var_1E; - } - obj->gobDestX = gobDestX; - obj->gobDestY = gobDestY; - objAnim->field_13 = gobDestX; - objAnim->field_14 = gobDestY; - if (objAnim->field_13 == -1) { - objAnim->field_13 = obj->goblinX; - obj->gobDestX = obj->goblinX; - } - if (objAnim->field_14 == -1) { - objAnim->field_14 = obj->goblinY; - obj->gobDestY = obj->goblinY; - } - } - } - _vm->_goblin->initiateMove(obj); + _vm->_goblin->move(destX, destY, index); } -void Inter_v2::o2_writeGoblinPos(void) { - int16 var1; - int16 var2; +void Inter_v2::o2_writeGoblinPos() { + int16 varX, varY; int16 index; - var1 = _vm->_parse->parseVarIndex(); - var2 = _vm->_parse->parseVarIndex(); + varX = _vm->_parse->parseVarIndex(); + varY = _vm->_parse->parseVarIndex(); index = _vm->_parse->parseValExpr(); - WRITE_VAR_OFFSET(var1, _vm->_mult->_objects[index].goblinX); - WRITE_VAR_OFFSET(var2, _vm->_mult->_objects[index].goblinY); + WRITE_VAR_OFFSET(varX, _vm->_mult->_objects[index].goblinX); + WRITE_VAR_OFFSET(varY, _vm->_mult->_objects[index].goblinY); } -void Inter_v2::o2_multSub(void) { - _vm->_mult->multSub(_vm->_parse->parseValExpr()); +void Inter_v2::o2_stopGoblin() { + int16 index = _vm->_parse->parseValExpr(); + + _vm->_mult->_objects[index].pAnimData->pathExistence = 4; } -void Inter_v2::o2_renderStatic(void) { - int16 layer; +void Inter_v2::o2_setGoblinState() { int16 index; + int16 state; + int16 type; + int16 layer; + int16 animation; + int16 deltaX, deltaY; + int16 deltaWidth, deltaHeight; index = _vm->_parse->parseValExpr(); - layer = _vm->_parse->parseValExpr(); - _vm->_scenery->renderStatic(index, layer); -} + state = _vm->_parse->parseValExpr(); + type = _vm->_parse->parseValExpr(); -void Inter_v2::loadMult(void) { - int16 val; - int16 objIndex; // si - int16 i; - int16 animation; - int16 layer; - char *lmultData; - Mult::Mult_Object *obj; - Mult::Mult_AnimData *objAnim; + Mult::Mult_Object &obj = _vm->_mult->_objects[index]; + Mult::Mult_AnimData &objAnim = *(obj.pAnimData); - debugC(4, kDebugGameFlow, "Inter_v2::loadMult(): Loading..."); + objAnim.stateType = type; + if (!obj.goblinStates[state]) + return; - objIndex = _vm->_parse->parseValExpr(); - val = _vm->_parse->parseValExpr(); - *_vm->_mult->_objects[objIndex].pPosX = val; - val = _vm->_parse->parseValExpr(); - *_vm->_mult->_objects[objIndex].pPosY = val; + Scenery::AnimLayer *animLayer; + switch (type) { + case 0: + objAnim.frame = 0; + layer = obj.goblinStates[state][0].layer; + animation = obj.goblinStates[state][0].animation; + objAnim.state = state; + objAnim.layer = layer; + objAnim.animation = animation; + + animLayer = _vm->_scenery->getAnimLayer(animation, layer); + *(obj.pPosX) = animLayer->posX; + *(obj.pPosY) = animLayer->posY; + objAnim.isPaused = 0; + objAnim.isStatic = 0; + objAnim.newCycle = animLayer->framesCount; + break; - lmultData = (char *)_vm->_mult->_objects[objIndex].pAnimData; - for (i = 0; i < 11; i++) { - if (*_vm->_global->_inter_execPtr != 99) - lmultData[i] = _vm->_parse->parseValExpr(); - else - _vm->_global->_inter_execPtr++; - } + case 1: + case 4: + case 6: + layer = obj.goblinStates[objAnim.state][0].layer; + animation = obj.goblinStates[objAnim.state][0].animation; + _vm->_scenery->updateAnim(layer, 0, animation, 0, + *(obj.pPosX), *(obj.pPosY), 0); + + deltaHeight = _vm->_scenery->_animBottom - _vm->_scenery->_animTop; + deltaWidth = _vm->_scenery->_animRight - _vm->_scenery->_animLeft; + + animLayer = + _vm->_scenery->getAnimLayer(objAnim.animation, objAnim.layer); + deltaX = animLayer->animDeltaX; + deltaY = animLayer->animDeltaY; + + layer = obj.goblinStates[state][0].layer; + animation = obj.goblinStates[state][0].animation; + objAnim.state = state; + objAnim.layer = layer; + objAnim.animation = animation; + objAnim.frame = 0; + objAnim.isPaused = 0; + objAnim.isStatic = 0; + + animLayer = _vm->_scenery->getAnimLayer(animation, layer); + objAnim.newCycle = animLayer->framesCount; + + _vm->_scenery->updateAnim(layer, 0, animation, 0, + *(obj.pPosX), *(obj.pPosY), 0); + + deltaHeight -= _vm->_scenery->_animBottom - _vm->_scenery->_animTop; + deltaWidth -= _vm->_scenery->_animRight - _vm->_scenery->_animLeft; + *(obj.pPosX) += deltaWidth + deltaX; + *(obj.pPosY) += deltaHeight + deltaY; + break; - if (_vm->_mult->_objects[objIndex].pAnimData->animType == 100) { - if (_vm->_goblin->_gobsCount >= 0) { - obj = &_vm->_mult->_objects[objIndex]; - objAnim = obj->pAnimData; - - val = *obj->pPosX % 256; - obj->destX = val; - obj->gobDestX = val; - obj->goblinX = val; - val = *obj->pPosY % 256; - obj->destY = val; - obj->gobDestY = val; - obj->goblinY = val; - *obj->pPosX *= _vm->_map->_tilesWidth; - layer = objAnim->layer; - animation = obj->goblinStates[layer][0].animation; - objAnim->field_15 = objAnim->unknown; - objAnim->nextState = -1; - objAnim->field_F = -1; - objAnim->pathExistence = 0; - objAnim->isBusy = 0; - objAnim->state = layer; - objAnim->layer = obj->goblinStates[objAnim->state][0].layer; - objAnim->animation = animation; - _vm->_scenery->updateAnim(layer, 0, animation, 0, *obj->pPosX, *obj->pPosY, 0); - if (!_vm->_map->_bigTiles) - *obj->pPosY = (obj->goblinY + 1) * _vm->_map->_tilesHeight - - (_vm->_scenery->_animBottom - _vm->_scenery->_animTop); - else - *obj->pPosY = ((obj->goblinY + 1) * _vm->_map->_tilesHeight) - - (_vm->_scenery->_animBottom - _vm->_scenery->_animTop) - - ((obj->goblinY + 1) / 2); - *obj->pPosX = obj->goblinX * _vm->_map->_tilesWidth; - } - } - if (_vm->_mult->_objects[objIndex].pAnimData->animType == 101) { - if (_vm->_goblin->_gobsCount >= 0) { - obj = &_vm->_mult->_objects[objIndex]; - objAnim = obj->pAnimData; - - layer = objAnim->layer; - animation = obj->goblinStates[layer][0].animation; - objAnim->nextState = -1; - objAnim->field_F = -1; - objAnim->state = layer; - objAnim->layer = obj->goblinStates[objAnim->state][0].layer; - objAnim->animation = animation; - if ((*obj->pPosX == 1000) && (*obj->pPosY == 1000)) { - *obj->pPosX = _vm->_scenery->_animations[objAnim->animation].layers[objAnim->layer].posX; - *obj->pPosY = _vm->_scenery->_animations[objAnim->animation].layers[objAnim->layer].posY; - } - _vm->_scenery->updateAnim(layer, 0, animation, 0, *obj->pPosX, *obj->pPosY, 0); - } + case 11: + layer = obj.goblinStates[state][0].layer; + animation = obj.goblinStates[state][0].animation; + objAnim.state = state; + objAnim.layer = layer; + objAnim.animation = animation; + objAnim.frame = 0; + objAnim.isPaused = 0; + objAnim.isStatic = 0; + + animLayer = _vm->_scenery->getAnimLayer(animation, layer); + objAnim.newCycle = animLayer->framesCount; + _vm->_scenery->updateAnim(layer, 0, animation, 0, + *(obj.pPosX), *(obj.pPosY), 0); + + if (_vm->_map->_bigTiles) + *(obj.pPosY) = ((obj.goblinY + 1) * _vm->_map->_tilesHeight) - + (_vm->_scenery->_animBottom - _vm->_scenery->_animTop) - + ((obj.goblinY + 1) / 2); + else + *(obj.pPosY) = ((obj.goblinY + 1) * _vm->_map->_tilesHeight) - + (_vm->_scenery->_animBottom - _vm->_scenery->_animTop); + *(obj.pPosX) = obj.goblinX * _vm->_map->_tilesWidth; + break; } } -bool Inter_v2::o2_getFreeMem(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 freeVar; - int16 maxFreeVar; +void Inter_v2::o2_placeGoblin() { + int16 index; + int16 x, y; + int16 state; - freeVar = _vm->_parse->parseVarIndex(); - maxFreeVar = _vm->_parse->parseVarIndex(); + index = _vm->_parse->parseValExpr(); + x = _vm->_parse->parseValExpr(); + y = _vm->_parse->parseValExpr(); + state = _vm->_parse->parseValExpr(); - // HACK - WRITE_VAR_OFFSET(freeVar, 1000000); - WRITE_VAR_OFFSET(maxFreeVar, 1000000); - WRITE_VAR(16, READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4); - return false; + _vm->_goblin->placeObject(0, 0, index, x, y, state); } -bool Inter_v2::o2_readData(char &cmdCount, int16 &counter, int16 &retFlag) { - int32 retSize; - int32 size; - int32 offset; - int16 dataVar; - int16 handle; - char *buf; - char tmp[4]; - - evalExpr(0); - dataVar = _vm->_parse->parseVarIndex(); - size = _vm->_parse->parseValExpr(); - evalExpr(0); - offset = _vm->_global->_inter_resVal; - - if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.inf")) { - _vm->loadGameData(SAVE_CAT, dataVar, size, offset); - return false; - } - else if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.cat")) { - _vm->loadGameData(SAVE_CAT, dataVar, size, offset); - return false; - } - else if (!scumm_stricmp(_vm->_global->_inter_resStr, "save.inf")) { - _vm->loadGameData(SAVE_SAV, dataVar, size, offset); - return false; - } - else if (!scumm_stricmp(_vm->_global->_inter_resStr, "bloc.inf")) { - _vm->loadGameData(SAVE_BLO, dataVar, size, offset); - return false; - } +void Inter_v2::o2_initScreen() { + int16 offY; + int16 videoMode; + int16 width, height; - if (size < 0) { - warning("Attempted to read a raw sprite from file \"%s\"", _vm->_global->_inter_resStr); - return false ; - } else if (size == 0) { - dataVar = 0; - size = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4; - } - buf = _vm->_global->_inter_variables + dataVar; - memset(_vm->_global->_inter_variablesSizes + dataVar, 0, size); + offY = load16(); - if (_vm->_global->_inter_resStr[0] == 0) { - WRITE_VAR(1, size); - return false; - } + videoMode = offY & 0xFF; + offY = (offY >> 8) & 0xFF; - WRITE_VAR(1, 1); - handle = _vm->_dataio->openData(_vm->_global->_inter_resStr); + width = _vm->_parse->parseValExpr(); + height = _vm->_parse->parseValExpr(); - if (handle < 0) - return false; + _vm->_global->_fakeVideoMode = videoMode; - _vm->_draw->animateCursor(4); - if (offset < 0) - _vm->_dataio->seekData(handle, -offset - 1, 2); - else - _vm->_dataio->seekData(handle, offset, 0); + // Some versions require this + if (videoMode == 0xD) + videoMode = 0x14; - if (((dataVar >> 2) == 59) && (size == 4)) { - retSize = _vm->_dataio->readData(handle, tmp, 4); - WRITE_VAR(59, READ_LE_UINT32(tmp)); - // The scripts in some versions divide through 256^3 then, - // effectively doing a LE->BE conversion - if ((_vm->_platform != Common::kPlatformPC) && (VAR(59) < 256)) - WRITE_VAR(59, SWAP_BYTES_32(VAR(59))); - } else - retSize = _vm->_dataio->readData(handle, buf, size); + if ((videoMode == _vm->_global->_videoMode) && (width == -1)) + return; - if (retSize == size) - WRITE_VAR(1, 0); + if (width > 0) + _vm->_video->_surfWidth = width; + if (height > 0) + _vm->_video->_surfHeight = height; + + _vm->_draw->closeScreen(); + _vm->_util->clearPalette(); + memset(_vm->_global->_redPalette, 0, 256); + memset(_vm->_global->_greenPalette, 0, 256); + memset(_vm->_global->_bluePalette, 0, 256); - _vm->_dataio->closeData(handle); - return false; -} + _vm->_global->_videoMode = videoMode; + _vm->_video->initPrimary(videoMode); + WRITE_VAR(15, _vm->_global->_fakeVideoMode); -bool Inter_v2::o2_writeData(char &cmdCount, int16 &counter, int16 &retFlag) { - int32 offset; - int32 size; - int16 dataVar; + _vm->_global->_setAllPalette = true; - evalExpr(0); - dataVar = _vm->_parse->parseVarIndex(); - size = _vm->_parse->parseValExpr(); - evalExpr(0); - offset = _vm->_global->_inter_resVal; + _vm->_util->setMousePos(_vm->_global->_inter_mouseX, + _vm->_global->_inter_mouseY); + _vm->_util->clearPalette(); - if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.inf")) - _vm->saveGameData(SAVE_CAT, dataVar, size, offset); - else if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.cat")) - _vm->saveGameData(SAVE_CAT, dataVar, size, offset); - else if (!scumm_stricmp(_vm->_global->_inter_resStr, "save.inf")) - _vm->saveGameData(SAVE_SAV, dataVar, size, offset); - else if (!scumm_stricmp(_vm->_global->_inter_resStr, "bloc.inf")) - _vm->saveGameData(SAVE_BLO, dataVar, size, offset); - else - warning("Attempted to write to file \"%s\"", _vm->_global->_inter_resStr); + _vm->_draw->initScreen(); - return false; + _vm->_util->setScrollOffset(); } -bool Inter_v2::o2_checkData(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 handle; - int16 varOff; - int32 size; +void Inter_v2::o2_scroll() { + int16 startX; + int16 startY; + int16 endX; + int16 endY; + int16 stepX; + int16 stepY; + int16 curX; + int16 curY; - evalExpr(0); - varOff = _vm->_parse->parseVarIndex(); + startX = _vm->_parse->parseValExpr(); + startY = _vm->_parse->parseValExpr(); + endX = _vm->_parse->parseValExpr(); + endY = _vm->_parse->parseValExpr(); + stepX = _vm->_parse->parseValExpr(); + stepY = _vm->_parse->parseValExpr(); - handle = 1; - if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.inf")) - size = _vm->getSaveSize(SAVE_CAT); - else if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.cat")) - size = _vm->getSaveSize(SAVE_CAT); - else if (!scumm_stricmp(_vm->_global->_inter_resStr, "save.inf")) - size = _vm->getSaveSize(SAVE_SAV); - else if (!scumm_stricmp(_vm->_global->_inter_resStr, "bloc.inf")) - size = _vm->getSaveSize(SAVE_BLO); - else { - handle = _vm->_dataio->openData(_vm->_global->_inter_resStr); + curX = startX; + curY = startY; + while (!_vm->_quitRequested && ((curX != endX) || (curY != endY))) { + curX = stepX > 0 ? MIN(curX + stepX, (int) endX) : + MAX(curX + stepX, (int) endX); + curY = stepY > 0 ? MIN(curY + stepY, (int) endY) : + MAX(curY + stepY, (int) endY); - if (handle >= 0) { - _vm->_dataio->closeData(handle); - size = _vm->_dataio->getDataSize(_vm->_global->_inter_resStr); - } else { - size = -1; - warning("File \"%s\" not found", _vm->_global->_inter_resStr); - } + _vm->_draw->_scrollOffsetX = curX; + _vm->_draw->_scrollOffsetY = curY; + _vm->_util->setScrollOffset(); } - if (size == -1) - handle = -1; +} - WRITE_VAR_OFFSET(varOff, handle); - WRITE_VAR(16, (uint32) size); +void Inter_v2::o2_setScrollOffset() { + int16 offset; - return false; -} + offset = _vm->_parse->parseValExpr(); -bool Inter_v2::o2_stopSound(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 expr; + if (offset == -1) { + _vm->_parse->parseValExpr(); + WRITE_VAR(2, _vm->_draw->_scrollOffsetX); + WRITE_VAR(3, _vm->_draw->_scrollOffsetY); + } else { + _vm->_draw->_scrollOffsetX = offset; + _vm->_draw->_scrollOffsetY = _vm->_parse->parseValExpr(); + } + _vm->_util->setScrollOffset(); + _noBusyWait = true; +} - expr = _vm->_parse->parseValExpr(); +void Inter_v2::o2_playImd() { + char imd[128]; + int16 x, y; + int16 startFrame; + int16 lastFrame; + int16 breakKey; + int16 flags; + int16 palStart; + int16 palEnd; + uint16 palCmd; + bool close; - if (expr < 0) { - if (_vm->_adlib) - _vm->_adlib->stopPlay(); - } else - _vm->_snd->stopSound(expr); + evalExpr(0); + _vm->_global->_inter_resStr[8] = 0; + strcpy(imd, _vm->_global->_inter_resStr); - _soundEndTimeKey = 0; - return false; -} + x = _vm->_parse->parseValExpr(); + y = _vm->_parse->parseValExpr(); + startFrame = _vm->_parse->parseValExpr(); + lastFrame = _vm->_parse->parseValExpr(); + breakKey = _vm->_parse->parseValExpr(); + flags = _vm->_parse->parseValExpr(); + palStart = _vm->_parse->parseValExpr(); + palEnd = _vm->_parse->parseValExpr(); + palCmd = 1 << (flags & 0x3F); + + if (!_vm->_imdPlayer->openImd(imd, x, y, startFrame, flags)) + return; -bool Inter_v2::o2_createSprite(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 index; - int16 height; - int16 width; - int16 flag; + close = (lastFrame == -1); + if (lastFrame < 0) + lastFrame = _vm->_imdPlayer->_curImd->framesCount - 1; - index = load16(); - width = load16(); - height = load16(); + for (int i = startFrame; i <= lastFrame; i++) { + _vm->_imdPlayer->play(i, palCmd, palStart, palEnd, 0, lastFrame); + WRITE_VAR(11, i); - _vm->_draw->adjustCoords(0, &width, &height); + if (breakKey != 0) { + _vm->_util->getMouseState(&_vm->_global->_inter_mouseX, + &_vm->_global->_inter_mouseY, &_vm->_game->_mouseButtons); - flag = load16(); + storeKey(_vm->_util->checkKey()); + if (VAR(0) == (unsigned) breakKey) + return; + } + } - _vm->_draw->initBigSprite(index, width, height, flag); - return false; + if (close) + _vm->_imdPlayer->closeImd(); } -bool Inter_v2::o2_animPalInit(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 index; +void Inter_v2::o2_getImdInfo() { + ImdPlayer::Imd *imd; + int16 varX, varY; + int16 varFrames; + int16 varWidth, varHeight; - index = load16(); - if (index > 0) { - index--; - _animPalLowIndex[index] = _vm->_parse->parseValExpr(); - _animPalHighIndex[index] = _vm->_parse->parseValExpr(); - _animPalDir[index] = 1; - } else if (index == 0) { - memset(_animPalDir, 0, 8 * sizeof(int16)); - _vm->_parse->parseValExpr(); - _vm->_parse->parseValExpr(); + evalExpr(0); + varX = _vm->_parse->parseVarIndex(); + varY = _vm->_parse->parseVarIndex(); + varFrames = _vm->_parse->parseVarIndex(); + varWidth = _vm->_parse->parseVarIndex(); + varHeight = _vm->_parse->parseVarIndex(); + imd = _vm->_imdPlayer->loadImdFile(_vm->_global->_inter_resStr, 0, 2); + if (!imd) { + WRITE_VAR_OFFSET(varX, -1); + WRITE_VAR_OFFSET(varY, -1); + WRITE_VAR_OFFSET(varFrames, -1); + WRITE_VAR_OFFSET(varWidth, -1); + WRITE_VAR_OFFSET(varHeight, -1); } else { - index = -index - 1; - _animPalLowIndex[index] = _vm->_parse->parseValExpr(); - _animPalHighIndex[index] = _vm->_parse->parseValExpr(); - _animPalDir[index] = -1; + WRITE_VAR_OFFSET(varX, imd->x); + WRITE_VAR_OFFSET(varY, imd->y); + WRITE_VAR_OFFSET(varFrames, imd->framesCount); + WRITE_VAR_OFFSET(varWidth, imd->width); + WRITE_VAR_OFFSET(varHeight, imd->height); } - return false; + _vm->_imdPlayer->finishImd(imd); } -bool Inter_v2::o2_playSound(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 frequency; - int16 freq2; - int16 repCount; // di - int16 index; // si - int16 endRep; - - index = _vm->_parse->parseValExpr(); - repCount = _vm->_parse->parseValExpr(); - frequency = _vm->_parse->parseValExpr(); +void Inter_v2::o2_openItk() { + char fileName[32]; - _soundEndTimeKey = 0; - if (_vm->_game->_soundSamples[index] == 0) - return false; - - if (repCount < 0) { - if (_vm->_global->_soundFlags < 2) - return false; + evalExpr(0); + strcpy(fileName, _vm->_global->_inter_resStr); + strcat(fileName, ".ITK"); - repCount = -repCount; - _soundEndTimeKey = _vm->_util->getTimeKey(); + _vm->_dataIO->openDataFile(fileName, true); +} - freq2 = frequency ? frequency : _vm->_game->_soundSamples[index]->frequency; - endRep = MAX(repCount - 1, 1); +void Inter_v2::o2_closeItk() { + _vm->_dataIO->closeDataFile(true); +} - _soundStopVal = - (10 * (_vm->_game->_soundSamples[index]->size / 2)) / freq2; - _soundEndTimeKey += - ((_vm->_game->_soundSamples[index]->size * endRep - - _vm->_game->_soundSamples[index]->size / 2) * 1000) / freq2; - } - if ((_vm->_game->_soundTypes[index] & 8)) { - if (_vm->_adlib) { - _vm->_adlib->load((byte *) _vm->_game->_soundSamples[index]->data, index); - _vm->_adlib->setRepeating(repCount - 1); - _vm->_adlib->startPlay(); - } - } else { - _vm->_snd->stopSound(0); - _vm->_snd->playSample(_vm->_game->_soundSamples[index], repCount - 1, frequency); +void Inter_v2::o2_setImdFrontSurf() { + _vm->_imdPlayer->_frontSurf = 21; + if (_vm->_global->_videoMode == 0x14) { + _vm->_imdPlayer->_frontMem = _vm->_draw->_frontSurface->getVidMem(); + _vm->_draw->blitInvalidated(); + _vm->_imdPlayer->_frontSurf = 20; } - - return false; } -bool Inter_v2::o2_goblinFunc(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 cmd; - int16 extraData; - - cmd = load16(); - _vm->_global->_inter_execPtr += 2; - - if (cmd != 101) - executeGoblinOpcode(cmd, extraData, NULL, NULL); - return false; +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); + } 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); } -bool Inter_v2::o2_evaluateStore(char &cmdCount, int16 &counter, int16 &retFlag) { +bool Inter_v2::o2_evaluateStore(OpFuncParams ¶ms) { char *savedPos; int16 varOff; int16 token; @@ -1643,9 +1616,9 @@ bool Inter_v2::o2_evaluateStore(char &cmdCount, int16 &counter, int16 &retFlag) return false; } -bool Inter_v2::o2_printText(char &cmdCount, int16 &counter, int16 &retFlag) { +bool Inter_v2::o2_printText(OpFuncParams ¶ms) { char buf[60]; - int16 i; + int i; _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); @@ -1663,732 +1636,278 @@ bool Inter_v2::o2_printText(char &cmdCount, int16 &counter, int16 &retFlag) { } do { - for (i = 0; *_vm->_global->_inter_execPtr != '.' && (byte)*_vm->_global->_inter_execPtr != 200; - i++, _vm->_global->_inter_execPtr++) { + for (i = 0; (*_vm->_global->_inter_execPtr != '.') && + ((byte) *_vm->_global->_inter_execPtr != 200); + i++, _vm->_global->_inter_execPtr++) { buf[i] = *_vm->_global->_inter_execPtr; } - if ((byte)*_vm->_global->_inter_execPtr != 200) { + if ((byte) *_vm->_global->_inter_execPtr != 200) { _vm->_global->_inter_execPtr++; switch (*_vm->_global->_inter_execPtr) { case 16: case 18: - sprintf(buf + i, "%d", (int8) READ_VARO_UINT8(_vm->_parse->parseVarIndex())); + sprintf(buf + i, "%d", + (int8) READ_VARO_UINT8(_vm->_parse->parseVarIndex())); break; case 17: case 24: case 27: - sprintf(buf + i, "%d", (int16) READ_VARO_UINT16(_vm->_parse->parseVarIndex())); + sprintf(buf + i, "%d", + (int16) READ_VARO_UINT16(_vm->_parse->parseVarIndex())); break; case 23: case 26: - sprintf(buf + i, "%d", VAR_OFFSET(_vm->_parse->parseVarIndex())); + sprintf(buf + i, "%d", + VAR_OFFSET(_vm->_parse->parseVarIndex())); break; case 25: case 28: - sprintf(buf + i, "%s", GET_VARO_STR(_vm->_parse->parseVarIndex())); + sprintf(buf + i, "%s", + GET_VARO_STR(_vm->_parse->parseVarIndex())); break; } _vm->_global->_inter_execPtr++; - } else { + } else buf[i] = 0; - } + _vm->_draw->spriteOperation(DRAW_PRINTTEXT); - } while ((byte)*_vm->_global->_inter_execPtr != 200); + } while ((byte) *_vm->_global->_inter_execPtr != 200); + _vm->_global->_inter_execPtr++; return false; } -bool Inter_v2::o2_palLoad(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 i; - int16 ind1; - int16 ind2; - byte cmd; - char *palPtr; - - cmd = *_vm->_global->_inter_execPtr++; - - switch (cmd & 0x7f) { - case 48: - if ((_vm->_global->_fakeVideoMode < 0x32) || (_vm->_global->_fakeVideoMode > 0x63)) { - _vm->_global->_inter_execPtr += 48; - return false; - } - break; - - case 49: - if ((_vm->_global->_fakeVideoMode != 5) && (_vm->_global->_fakeVideoMode != 7)) { - _vm->_global->_inter_execPtr += 18; - return false; - } - break; - - case 50: - if (_vm->_global->_colorCount == 256) { - _vm->_global->_inter_execPtr += 16; - return false; - } - break; - - case 51: - if (_vm->_global->_fakeVideoMode < 0x64) { - _vm->_global->_inter_execPtr += 2; - return false; - } - break; - - case 52: - if (_vm->_global->_colorCount == 256) { - _vm->_global->_inter_execPtr += 48; - return false; - } - break; - - case 53: - if (_vm->_global->_colorCount != 256) { - _vm->_global->_inter_execPtr += 2; - return false; - } - break; - - case 54: - if (_vm->_global->_fakeVideoMode < 0x13) { - return false; - } - break; - - case 61: - if (_vm->_global->_fakeVideoMode < 0x13) { - *_vm->_global->_inter_execPtr += 4; - return false; - } - break; - } - - if ((cmd & 0x7f) == 0x30) { - _vm->_global->_inter_execPtr += 48; - return false; - } - - _vm->_draw->_applyPal = 0; - if (cmd & 0x80) - cmd &= 0x7f; - else - _vm->_draw->_applyPal = 1; - - if (cmd == 49) { - int dl = 0; - for (i = 2; i < 18; i++) { - dl = 1; - if (_vm->_global->_inter_execPtr[i] != 0) - dl = 0; - } - if (dl != 0) { - warning("GOB2 Stub! sub_27413"); -/* sub_27413(_draw_frontSurface); - byte_2E521 = 0; - _vm->_global->_inter_execPtr += 18; - break;*/ - } -// byte_2E521 = 1; - - for (i = 0; i < 18; i++, _vm->_global->_inter_execPtr++) { - if (i < 2) { - if (_vm->_draw->_applyPal == 0) - continue; - - _vm->_draw->_unusedPalette1[i] = *_vm->_global->_inter_execPtr; - continue; - } - - ind1 = *_vm->_global->_inter_execPtr >> 4; - ind2 = (*_vm->_global->_inter_execPtr & 0xf); - - _vm->_draw->_unusedPalette1[i] = - ((_vm->_draw->_palLoadData1[ind1] + _vm->_draw->_palLoadData2[ind2]) << 8) + - (_vm->_draw->_palLoadData2[ind1] + _vm->_draw->_palLoadData1[ind2]); - } - - _vm->_global->_pPaletteDesc->unused1 = _vm->_draw->_unusedPalette1; - _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); - return false; - } - - switch (cmd) { - case 50: - for (i = 0; i < 16; i++, _vm->_global->_inter_execPtr++) - _vm->_draw->_unusedPalette2[i] = *_vm->_global->_inter_execPtr; - break; - - case 52: - for (i = 0; i < 16; i++, _vm->_global->_inter_execPtr += 3) { - _vm->_draw->_vgaPalette[i].red = _vm->_global->_inter_execPtr[0]; - _vm->_draw->_vgaPalette[i].green = _vm->_global->_inter_execPtr[1]; - _vm->_draw->_vgaPalette[i].blue = _vm->_global->_inter_execPtr[2]; - } - break; - - case 53: - palPtr = _vm->_game->loadTotResource(_vm->_inter->load16()); - memcpy((char *)_vm->_draw->_vgaPalette, palPtr, 768); - break; - - case 54: - memset((char *)_vm->_draw->_vgaPalette, 0, 768); - break; +bool Inter_v2::o2_animPalInit(OpFuncParams ¶ms) { + int16 index; - case 61: - ind1 = *_vm->_global->_inter_execPtr++; - ind2 = (*_vm->_global->_inter_execPtr++ - ind1 + 1) * 3; - palPtr = _vm->_game->loadTotResource(_vm->_inter->load16()); - memcpy((char *)_vm->_draw->_vgaPalette + ind1 * 3, palPtr + ind1 * 3, ind2); - if (_vm->_draw->_applyPal) { - _vm->_draw->_applyPal = 0; - _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); - return false; - } - break; - } - - if (!_vm->_draw->_applyPal) { - _vm->_global->_pPaletteDesc->unused2 = _vm->_draw->_unusedPalette2; - _vm->_global->_pPaletteDesc->unused1 = _vm->_draw->_unusedPalette1; - if (_vm->_global->_videoMode < 0x13) { - _vm->_global->_pPaletteDesc->vgaPal = (Video::Color *)_vm->_draw->_vgaSmallPalette; - _vm->_palanim->fade((Video::PalDesc *) _vm->_global->_pPaletteDesc, 0, 0); - return false; - } - if ((_vm->_global->_videoMode < 0x32) || (_vm->_global->_videoMode >= 0x64)) { - _vm->_global->_pPaletteDesc->vgaPal = (Video::Color *)_vm->_draw->_vgaPalette; - _vm->_palanim->fade((Video::PalDesc *) _vm->_global->_pPaletteDesc, 0, 0); - return false; - } - _vm->_global->_pPaletteDesc->vgaPal = (Video::Color *)_vm->_draw->_vgaSmallPalette; - _vm->_palanim->fade((Video::PalDesc *) _vm->_global->_pPaletteDesc, 0, 0); + index = load16(); + if (index > 0) { + index--; + _animPalLowIndex[index] = _vm->_parse->parseValExpr(); + _animPalHighIndex[index] = _vm->_parse->parseValExpr(); + _animPalDir[index] = 1; + } else if (index == 0) { + memset(_animPalDir, 0, 8 * sizeof(int16)); + _vm->_parse->parseValExpr(); + _vm->_parse->parseValExpr(); + } else { + index = -index - 1; + _animPalLowIndex[index] = _vm->_parse->parseValExpr(); + _animPalHighIndex[index] = _vm->_parse->parseValExpr(); + _animPalDir[index] = -1; } - return false; } -bool Inter_v2::o2_loadTot(char &cmdCount, int16 &counter, int16 &retFlag) { - char buf[20]; - int8 size; - int16 i; - - if ((*_vm->_global->_inter_execPtr & 0x80) != 0) { - _vm->_global->_inter_execPtr++; - evalExpr(0); - strcpy(buf, _vm->_global->_inter_resStr); - } else { - size = *_vm->_global->_inter_execPtr++; - for (i = 0; i < size; i++) - buf[i] = *_vm->_global->_inter_execPtr++; - - buf[size] = 0; - } - - if (strcmp(buf, "INSTALL") == 0) { - warning("GOB2 Stub! word_2E515 = _inter_variables[0E8h]"); - } +bool Inter_v2::o2_goblinFunc(OpFuncParams ¶ms) { + OpGobParams gobParams; + int16 cmd; - strcat(buf, ".tot"); - if (_terminate != 2) - _terminate = true; - strcpy(_vm->_game->_totToLoad, buf); + cmd = load16(); + _vm->_global->_inter_execPtr += 2; + if (cmd != 101) + executeGoblinOpcode(cmd, gobParams); return false; } -bool Inter_v2::o2_freeSprite(char &cmdCount, int16 &counter, int16 &retFlag) { +bool Inter_v2::o2_createSprite(OpFuncParams ¶ms) { int16 index; + int16 width, height; + int16 flag; index = load16(); - if (_vm->_draw->_spritesArray[index] == 0) - return false; + width = load16(); + height = load16(); - _vm->_draw->freeSprite(index); + _vm->_draw->adjustCoords(0, &width, &height); - return false; -} + flag = load16(); + _vm->_draw->initSpriteSurf(index, width, height, flag); -bool Inter_v2::o2_loadSound(char &cmdCount, int16 &counter, int16 &retFlag) { - loadSound(0); return false; } -void Inter_v2::o2_setRenderFlags(void) { +bool Inter_v2::o2_stopSound(OpFuncParams ¶ms) { int16 expr; expr = _vm->_parse->parseValExpr(); - - if (expr & 0x8000) { - _vm->_draw->_renderFlags |= expr & 0x3fff; - } - else { - if (expr & 0x4000) - _vm->_draw->_renderFlags &= expr & 0x3fff; - else - _vm->_draw->_renderFlags = expr; - } -} - -void Inter_v2::o2_initMult(void) { - int16 oldAnimHeight; - int16 oldAnimWidth; - int16 oldObjCount; - int16 i; - int16 posXVar; - int16 posYVar; - int16 animDataVar; - - oldAnimWidth = _vm->_anim->_areaWidth; - oldAnimHeight = _vm->_anim->_areaHeight; - oldObjCount = _vm->_mult->_objCount; - - _vm->_anim->_areaLeft = load16(); - _vm->_anim->_areaTop = load16(); - _vm->_anim->_areaWidth = load16(); - _vm->_anim->_areaHeight = load16(); - _vm->_mult->_objCount = load16(); - posXVar = _vm->_parse->parseVarIndex(); - posYVar = _vm->_parse->parseVarIndex(); - animDataVar = _vm->_parse->parseVarIndex(); - - if (_vm->_mult->_objects && (oldObjCount != _vm->_mult->_objCount)) { - warning("Initializing new objects without having cleaned up the old ones at first"); - delete[] _vm->_mult->_objects; - delete[] _vm->_mult->_renderData2; - delete[] _vm->_mult->_orderArray; - _vm->_mult->_objects = 0; - _vm->_mult->_renderData2 = 0; - _vm->_mult->_orderArray = 0; - } - - if (_vm->_mult->_objects == 0) { - _vm->_mult->_renderData2 = new Mult::Mult_Object*[_vm->_mult->_objCount]; - memset(_vm->_mult->_renderData2, 0, _vm->_mult->_objCount * sizeof(Mult::Mult_Object*)); - if (_terminate) - return; - _vm->_mult->_orderArray = new int8[_vm->_mult->_objCount]; - memset(_vm->_mult->_orderArray, 0, _vm->_mult->_objCount * sizeof(int8)); - _vm->_mult->_objects = new Mult::Mult_Object[_vm->_mult->_objCount]; - memset(_vm->_mult->_objects, 0, _vm->_mult->_objCount * sizeof(Mult::Mult_Object)); - - for (i = 0; i < _vm->_mult->_objCount; i++) { - _vm->_mult->_objects[i].pPosX = (int32 *)(_vm->_global->_inter_variables + i * 4 + (posXVar / 4) * 4); - _vm->_mult->_objects[i].pPosY = (int32 *)(_vm->_global->_inter_variables + i * 4 + (posYVar / 4) * 4); - _vm->_mult->_objects[i].pAnimData = - (Mult::Mult_AnimData *) (_vm->_global->_inter_variables + animDataVar + - i * 4 * _vm->_global->_inter_animDataSize); - memset(_vm->_global->_inter_variablesSizes + i * 4 * _vm->_global->_inter_animDataSize, 0, - _vm->_global->_inter_animDataSize); - - _vm->_mult->_objects[i].pAnimData->isStatic = 1; - _vm->_mult->_objects[i].tick = 0; - _vm->_mult->_objects[i].lastLeft = -1; - _vm->_mult->_objects[i].lastRight = -1; - _vm->_mult->_objects[i].lastTop = -1; - _vm->_mult->_objects[i].lastBottom = -1; - _vm->_mult->_objects[i].goblinX = 1; - _vm->_mult->_objects[i].goblinY = 1; - } - } - - if (_vm->_anim->_animSurf != 0 && - (oldAnimWidth != _vm->_anim->_areaWidth - || oldAnimHeight != _vm->_anim->_areaHeight)) { - if (_vm->_anim->_animSurf->vidMode & 0x80) - _vm->_draw->freeSprite(22); - else - delete _vm->_anim->_animSurf; - _vm->_draw->_spritesArray[22] = 0; - _vm->_anim->_animSurf = 0; - } - - _vm->_draw->adjustCoords(0, &_vm->_anim->_areaWidth, &_vm->_anim->_areaHeight); - if (_vm->_anim->_animSurf == 0) { - _vm->_draw->initBigSprite(22, _vm->_anim->_areaWidth, _vm->_anim->_areaHeight, 0); - _vm->_anim->_animSurf = _vm->_draw->_spritesArray[22]; - if (_terminate) - return; - } - - _vm->_draw->adjustCoords(1, &_vm->_anim->_areaWidth, &_vm->_anim->_areaHeight); - _vm->_draw->_sourceSurface = 21; - _vm->_draw->_destSurface = 22; - _vm->_draw->_spriteLeft = _vm->_anim->_areaLeft; - _vm->_draw->_spriteTop = _vm->_anim->_areaTop; - _vm->_draw->_spriteRight = _vm->_anim->_areaWidth; - _vm->_draw->_spriteBottom = _vm->_anim->_areaHeight; - _vm->_draw->_destSpriteX = 0; - _vm->_draw->_destSpriteY = 0; - _vm->_draw->spriteOperation(0); - - debugC(4, kDebugGraphics, "o2_initMult: x = %d, y = %d, w = %d, h = %d", - _vm->_anim->_areaLeft, _vm->_anim->_areaTop, _vm->_anim->_areaWidth, _vm->_anim->_areaHeight); - debugC(4, kDebugGraphics, " _vm->_mult->_objCount = %d, animation data size = %d", _vm->_mult->_objCount, _vm->_global->_inter_animDataSize); -} - -void Inter_v2::o2_getObjAnimSize(void) { - Mult::Mult_AnimData *pAnimData; - int16 objIndex; - - objIndex = _vm->_parse->parseValExpr(); - pAnimData = _vm->_mult->_objects[objIndex].pAnimData; - if (pAnimData->isStatic == 0) { - _vm->_scenery->updateAnim(pAnimData->layer, pAnimData->frame, - pAnimData->animation, 0, *(_vm->_mult->_objects[objIndex].pPosX), - *(_vm->_mult->_objects[objIndex].pPosY), 0); - } - _vm->_scenery->_toRedrawLeft = MAX(_vm->_scenery->_toRedrawLeft, (int16) 0); - _vm->_scenery->_toRedrawTop = MAX(_vm->_scenery->_toRedrawTop, (int16) 0); - WRITE_VAR_OFFSET(_vm->_parse->parseVarIndex(), _vm->_scenery->_toRedrawLeft); - WRITE_VAR_OFFSET(_vm->_parse->parseVarIndex(), _vm->_scenery->_toRedrawTop); - WRITE_VAR_OFFSET(_vm->_parse->parseVarIndex(), _vm->_scenery->_toRedrawRight); - WRITE_VAR_OFFSET(_vm->_parse->parseVarIndex(), _vm->_scenery->_toRedrawBottom); -} - -void Inter_v2::o2_loadCurLayer(void) { - _vm->_scenery->_curStatic = _vm->_parse->parseValExpr(); - _vm->_scenery->_curStaticLayer = _vm->_parse->parseValExpr(); -} - -void Inter_v2::o2_playCDTrack(void) { - if ((_vm->_draw->_renderFlags & 0x200) == 0) - _vm->_draw->blitInvalidated(); - evalExpr(NULL); - _vm->_cdrom->startTrack(_vm->_global->_inter_resStr); -} - -void Inter_v2::o2_stopCD(void) { - _vm->_cdrom->stopPlaying(); -} - -void Inter_v2::o2_readLIC(void) { - byte result; - char path[40]; - - result = evalExpr(NULL); - strcpy(path, _vm->_global->_inter_resStr); - strcat(path, ".LIC"); - _vm->_cdrom->readLIC(path); -} - -void Inter_v2::o2_freeLIC(void) { - _vm->_cdrom->freeLICbuffer(); -} - -void Inter_v2::o2_getCDTrackPos(void) { - int16 varPos; - int16 varName; - - _vm->_util->longDelay(1); - - varPos = _vm->_parse->parseVarIndex(); - varName = _vm->_parse->parseVarIndex(); + if (expr < 0) { + if (_vm->_adlib) + _vm->_adlib->stopPlay(); + } else + _vm->_snd->stopSound(expr); - WRITE_VAR_OFFSET(varPos, _vm->_cdrom->getTrackPos()); - WRITE_VARO_STR(varName, _vm->_cdrom->getCurTrack()); + _soundEndTimeKey = 0; + return false; } -void Inter_v2::o2_playMult(void) { - int16 checkEscape; - - checkEscape = load16(); - - _vm->_mult->setMultData(checkEscape >> 1); - _vm->_mult->playMult(VAR(57), -1, checkEscape & 0x1, 0); +bool Inter_v2::o2_loadSound(OpFuncParams ¶ms) { + loadSound(0); + return false; } -void Inter_v2::o2_initCursor(void) { - int16 width; - int16 height; - int16 count; - int16 i; - - _vm->_draw->_cursorXDeltaVar = _vm->_parse->parseVarIndex() / 4; - _vm->_draw->_cursorYDeltaVar = _vm->_parse->parseVarIndex() / 4; - - width = load16(); - if (width < 16) - width = 16; - - height = load16(); - if (height < 16) - height = 16; - - _vm->_draw->adjustCoords(0, &width, &height); - - count = load16(); - if (count < 2) - count = 2; - - if (width != _vm->_draw->_cursorWidth || height != _vm->_draw->_cursorHeight || - _vm->_draw->_cursorSprites->width != width * count) { - - _vm->_draw->freeSprite(23); - _vm->_draw->_cursorSprites = 0; - _vm->_draw->_cursorSpritesBack = 0; - - _vm->_video->freeSurfDesc(_vm->_draw->_scummvmCursor); - _vm->_draw->_scummvmCursor = 0; +bool Inter_v2::o2_getFreeMem(OpFuncParams ¶ms) { + int16 freeVar; + int16 maxFreeVar; - _vm->_draw->_cursorWidth = width; - _vm->_draw->_cursorHeight = height; + freeVar = _vm->_parse->parseVarIndex(); + maxFreeVar = _vm->_parse->parseVarIndex(); - if (count < 0x80) - _vm->_draw->_transparentCursor = 1; - else - _vm->_draw->_transparentCursor = 0; - - if (count > 0x80) - count -= 0x80; - - _vm->_draw->initBigSprite(23, _vm->_draw->_cursorWidth * count, - _vm->_draw->_cursorHeight, 2); - _vm->_draw->_cursorSpritesBack = _vm->_draw->_spritesArray[23]; - _vm->_draw->_cursorSprites = _vm->_draw->_cursorSpritesBack; - - _vm->_draw->_scummvmCursor = - _vm->_video->initSurfDesc(_vm->_global->_videoMode, _vm->_draw->_cursorWidth, - _vm->_draw->_cursorHeight, SCUMMVM_CURSOR); - for (i = 0; i < 40; i++) { - _vm->_draw->_cursorAnimLow[i] = -1; - _vm->_draw->_cursorAnimDelays[i] = 0; - _vm->_draw->_cursorAnimHigh[i] = 0; - } - _vm->_draw->_cursorAnimLow[1] = 0; - } + // HACK + WRITE_VAR_OFFSET(freeVar, 1000000); + WRITE_VAR_OFFSET(maxFreeVar, 1000000); + WRITE_VAR(16, READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4); + return false; } -void Inter_v2::o2_playImd(void) { - char imd[128]; - int i; - int16 x; - int16 y; - int16 startFrame; // di - int16 lastFrame; // si - int16 breakKey; - int16 flags; - int16 expr7; - int16 expr8; +bool Inter_v2::o2_checkData(OpFuncParams ¶ms) { + int16 handle; + int16 varOff; + int32 size; evalExpr(0); - _vm->_global->_inter_resStr[8] = 0; - strcpy(imd, _vm->_global->_inter_resStr); - x = _vm->_parse->parseValExpr(); - y = _vm->_parse->parseValExpr(); - startFrame = _vm->_parse->parseValExpr(); - lastFrame = _vm->_parse->parseValExpr(); - breakKey = _vm->_parse->parseValExpr(); - flags = _vm->_parse->parseValExpr(); - expr7 = _vm->_parse->parseValExpr(); - expr8 = _vm->_parse->parseValExpr(); - - if (_vm->_game->openImd(imd, x, y, startFrame, flags) == 0) - return; + varOff = _vm->_parse->parseVarIndex(); - int16 var_C; + handle = 1; + if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.inf")) + size = _vm->getSaveSize(SAVE_CAT); + else if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.cat")) + size = _vm->getSaveSize(SAVE_CAT); + else if (!scumm_stricmp(_vm->_global->_inter_resStr, "save.inf")) + size = _vm->getSaveSize(SAVE_SAV); + else if (!scumm_stricmp(_vm->_global->_inter_resStr, "bloc.inf")) + size = _vm->getSaveSize(SAVE_BLO); + else { + handle = _vm->_dataIO->openData(_vm->_global->_inter_resStr); - var_C = lastFrame; - if (lastFrame < 0) - lastFrame = _vm->_game->_imdFile->framesCount - 1; - for (i = startFrame; i <= lastFrame; i++) { - _vm->_game->playImd(i, 1 << (flags & 0x3F), expr7, expr8, 0, lastFrame); - WRITE_VAR(11, i); - 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) - return; + if (handle >= 0) { + _vm->_dataIO->closeData(handle); + size = _vm->_dataIO->getDataSize(_vm->_global->_inter_resStr); + } else { + size = -1; + warning("File \"%s\" not found", _vm->_global->_inter_resStr); } } - if (var_C == -1) - _vm->_game->closeImd(); -} - -void Inter_v2::o2_initScreen(void) { - int16 offY; - int16 videoMode; - int16 width; - int16 height; - - offY = load16(); - - videoMode = offY & 0xFF; - offY = (offY >> 8) & 0xFF; - - width = _vm->_parse->parseValExpr(); - height = _vm->_parse->parseValExpr(); + if (size == -1) + handle = -1; - _vm->_global->_fakeVideoMode = videoMode; + WRITE_VAR_OFFSET(varOff, handle); + WRITE_VAR(16, (uint32) size); - // Some versions require this - if (videoMode == 0xD) - videoMode = 0x14; + return false; +} - if ((videoMode == _vm->_global->_videoMode) && (width == -1)) - return; +bool Inter_v2::o2_readData(OpFuncParams ¶ms) { + int32 retSize; + int32 size; + int32 offset; + int16 dataVar; + int16 handle; + char *buf; + char tmp[4]; - if (width > 0) - _vm->_video->_surfWidth = width; - if (height > 0) - _vm->_video->_surfHeight = height; - - _vm->_draw->closeScreen(); - _vm->_util->clearPalette(); - memset(_vm->_global->_redPalette, 0, 256); - memset(_vm->_global->_greenPalette, 0, 256); - memset(_vm->_global->_bluePalette, 0, 256); + evalExpr(0); + dataVar = _vm->_parse->parseVarIndex(); + size = _vm->_parse->parseValExpr(); + evalExpr(0); + offset = _vm->_global->_inter_resVal; - if (videoMode == 0x10) { - _vm->_global->_videoMode = 0x12; - _vm->_video->initPrimary(0xE); - _vm->_global->_videoMode = 0x10; - warning("GOB2 Stub! Set VGA CRT Maximum Scan Line to 0"); - _vm->_draw->_frontSurface->height = 400; - } else { - _vm->_global->_videoMode = videoMode; - _vm->_video->initPrimary(videoMode); + if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.inf")) { + _vm->loadGameData(SAVE_CAT, dataVar, size, offset); + return false; } - WRITE_VAR(15, _vm->_global->_fakeVideoMode); - - _vm->_global->_setAllPalette = 1; - - if ((width != -1) && (_vm->_global->_videoMode == 0x14)) - _vm->_game->_byte_2FC9B = 1; - - _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY); - _vm->_util->clearPalette(); - - // Split screen (word_2E51F ^= splitScreenHeight, off_2E51B ^= splitScreenSurf)? - if (offY == 0) - _vm->_draw->_word_2E51F = 0; - else - _vm->_draw->_word_2E51F = _vm->_global->_primaryHeight - offY; - _vm->_draw->initScreen(); - - _vm->_util->setScrollOffset(); - -/* - if (_vm->_draw->_off_2E51B != 0) { - warning("_vid_setSplit(%d)", _vm->_global->_primaryHeight - offY); - warning("_vid_setPixelShift(0, %d", offY); + else if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.cat")) { + _vm->loadGameData(SAVE_CAT, dataVar, size, offset); + return false; + } + else if (!scumm_stricmp(_vm->_global->_inter_resStr, "save.inf")) { + _vm->loadGameData(SAVE_SAV, dataVar, size, offset); + return false; + } + else if (!scumm_stricmp(_vm->_global->_inter_resStr, "bloc.inf")) { + _vm->loadGameData(SAVE_BLO, dataVar, size, offset); + return false; } -*/ -} -void Inter_v2::o2_setScrollOffset(void) { - int16 offset; + if (size < 0) { + warning("Attempted to read a raw sprite from file \"%s\"", + _vm->_global->_inter_resStr); + return false ; + } else if (size == 0) { + dataVar = 0; + size = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4; + } - offset = _vm->_parse->parseValExpr(); + buf = _vm->_global->_inter_variables + dataVar; + memset(_vm->_global->_inter_variablesSizes + dataVar, 0, size); - if (offset == -1) { - if (_vm->_game->_byte_2FC9B != 0) - _vm->_game->_byte_2FC9B = 1; - _vm->_parse->parseValExpr(); - WRITE_VAR(2, _vm->_draw->_scrollOffsetX); - WRITE_VAR(3, _vm->_draw->_scrollOffsetY); - } else { - _vm->_draw->_scrollOffsetX = offset; - _vm->_draw->_scrollOffsetY = _vm->_parse->parseValExpr(); + if (_vm->_global->_inter_resStr[0] == 0) { + WRITE_VAR(1, size); + return false; } - if (_vm->_draw->_off_2E51B != 0) - _vm->_util->setScrollOffset(_vm->_draw->_scrollOffsetX, - _vm->_draw->_scrollOffsetY + 200 - _vm->_draw->_word_2E51F); - else - _vm->_util->setScrollOffset(); - _noBusyWait = true; -/* - if (_vm->_draw->_off_2E51B != 0) - warning("_vid_setPixelShift(%d, %d)", _vm->_draw->_scrollOffsetX, _vm->_draw->_scrollOffsetY + 200 - _vm->_draw->_word_2E51F); - else - warning("_vid_setPixelShift(%d, %d)", _vm->_draw->_scrollOffsetX, _vm->_draw->_scrollOffsetY); -*/ -} - -void Inter_v2::o2_scroll(void) { - int16 startX; - int16 startY; - int16 endX; - int16 endY; - int16 stepX; - int16 stepY; - int16 curX; - int16 curY; + WRITE_VAR(1, 1); + handle = _vm->_dataIO->openData(_vm->_global->_inter_resStr); - startX = _vm->_parse->parseValExpr(); - startY = _vm->_parse->parseValExpr(); - endX = _vm->_parse->parseValExpr(); - endY = _vm->_parse->parseValExpr(); - stepX = _vm->_parse->parseValExpr(); - stepY = _vm->_parse->parseValExpr(); + if (handle < 0) + return false; - curX = startX; - curY = startY; - while (!_vm->_quitRequested && ((curX != endX) || (curY != endY))) { - curX = stepX > 0 ? MIN(curX + stepX, (int) endX) : MAX(curX + stepX, (int) endX); - curY = stepY > 0 ? MIN(curY + stepY, (int) endY) : MAX(curY + stepY, (int) endY); - _vm->_draw->_scrollOffsetX = curX; - _vm->_draw->_scrollOffsetY = curY; - _vm->_util->setScrollOffset(); - } -} + _vm->_draw->animateCursor(4); + if (offset < 0) + _vm->_dataIO->seekData(handle, -offset - 1, 2); + else + _vm->_dataIO->seekData(handle, offset, 0); -void Inter_v2::o2_totSub(void) { - char totFile[14]; - byte length; - int flags; - int i; + if (((dataVar >> 2) == 59) && (size == 4)) { + retSize = _vm->_dataIO->readData(handle, tmp, 4); + WRITE_VAR(59, READ_LE_UINT32(tmp)); + // The scripts in some versions divide through 256^3 then, + // effectively doing a LE->BE conversion + if ((_vm->_platform != Common::kPlatformPC) && (VAR(59) < 256)) + WRITE_VAR(59, SWAP_BYTES_32(VAR(59))); + } else + retSize = _vm->_dataIO->readData(handle, buf, size); - length = *_vm->_global->_inter_execPtr++; - if ((length & 0x7F) > 13) - error("Length in o2_totSub is greater than 13 (%d)", length); - if (length & 0x80) { - evalExpr(0); - strcpy(totFile, _vm->_global->_inter_resStr); - } else { - for (i = 0; i < length; i++) - totFile[i] = *_vm->_global->_inter_execPtr++; - totFile[i] = 0; - } + if (retSize == size) + WRITE_VAR(1, 0); - // WORKAROUND: There is a race condition in the script when opening the notepad - if (!scumm_stricmp(totFile, "edit")) - _vm->_util->forceMouseUp(); - flags = (byte) *_vm->_global->_inter_execPtr++; - _vm->_game->totSub(flags, totFile); + _vm->_dataIO->closeData(handle); + return false; } -void Inter_v2::o2_switchTotSub(void) { - int16 index; - int16 skipPlay; +bool Inter_v2::o2_writeData(OpFuncParams ¶ms) { + int32 offset; + int32 size; + int16 dataVar; - index = load16(); - skipPlay = load16(); + evalExpr(0); + dataVar = _vm->_parse->parseVarIndex(); + size = _vm->_parse->parseValExpr(); + evalExpr(0); + offset = _vm->_global->_inter_resVal; - _vm->_game->switchTotSub(index, skipPlay); -} + if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.inf")) + _vm->saveGameData(SAVE_CAT, dataVar, size, offset); + else if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.cat")) + _vm->saveGameData(SAVE_CAT, dataVar, size, offset); + else if (!scumm_stricmp(_vm->_global->_inter_resStr, "save.inf")) + _vm->saveGameData(SAVE_SAV, dataVar, size, offset); + else if (!scumm_stricmp(_vm->_global->_inter_resStr, "bloc.inf")) + _vm->saveGameData(SAVE_BLO, dataVar, size, offset); + else + warning("Attempted to write to file \"%s\"", _vm->_global->_inter_resStr); -void Inter_v2::o2_handleGoblins(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) { - _vm->_goblin->_word_2F9C0 = VAR(load16()); - _vm->_goblin->_word_2F9BE = VAR(load16()); - _vm->_goblin->_dword_2F9B6 = load16(); - _vm->_goblin->_dword_2F9B2 = load16(); - _vm->_goblin->_word_2F9BC = VAR(load16()); - _vm->_goblin->_word_2F9BA = VAR(load16()); - _vm->_goblin->handleGoblins(); + return false; } -void Inter_v2::o2_loadInfogramesIns(int16 &extraData, int32 *retVarPtr, - Goblin::Gob_Object *objDesc) { +void Inter_v2::o2_loadInfogramesIns(OpGobParams ¶ms) { int16 varName; char fileName[20]; @@ -2399,7 +1918,8 @@ void Inter_v2::o2_loadInfogramesIns(int16 &extraData, int32 *retVarPtr, strcpy(fileName, GET_VAR_STR(varName)); strcat(fileName, ".INS"); - debugC(1, kDebugMusic, "Loading Infogrames instrument file \"%s\"", fileName); + debugC(1, kDebugMusic, "Loading Infogrames instrument file \"%s\"", + fileName); if (_vm->_game->_infogrames) { _vm->_mixer->stopHandle(_vm->_game->_infHandle); @@ -2417,8 +1937,7 @@ void Inter_v2::o2_loadInfogramesIns(int16 &extraData, int32 *retVarPtr, } } -void Inter_v2::o2_playInfogrames(int16 &extraData, int32 *retVarPtr, - Goblin::Gob_Object *objDesc) { +void Inter_v2::o2_playInfogrames(OpGobParams ¶ms) { int16 varName; char fileName[20]; @@ -2430,19 +1949,24 @@ void Inter_v2::o2_playInfogrames(int16 &extraData, int32 *retVarPtr, strcpy(fileName, GET_VAR_STR(varName)); strcat(fileName, ".DUM"); debugC(1, kDebugMusic, "Playing Infogrames music file \"%s\"", fileName); + if (!_vm->_game->_infIns) { _vm->_game->_infIns = new Audio::Infogrames::Instruments; + if (!_vm->_game->_infIns->load("i1.ins")) { warning("Couldn't load instruments file"); delete _vm->_game->_infIns; _vm->_game->_infIns = 0; } } + if (_vm->_game->_infIns) { _vm->_mixer->stopHandle(_vm->_game->_infHandle); _vm->_game->_infogrames = new Audio::Infogrames(*_vm->_game->_infIns, true, - _vm->_mixer->getOutputRate(), _vm->_mixer->getOutputRate() / 75); + _vm->_mixer->getOutputRate(), + _vm->_mixer->getOutputRate() / 75); + if (!_vm->_game->_infogrames->load(fileName)) { warning("Couldn't load infogrames music"); delete _vm->_game->_infogrames; @@ -2453,49 +1977,87 @@ void Inter_v2::o2_playInfogrames(int16 &extraData, int32 *retVarPtr, } } -void Inter_v2::storeKey(int16 key) { - WRITE_VAR(12, _vm->_util->getTimeKey() - _vm->_game->_startTimeKey); - - storeMouse(); - WRITE_VAR(1, _vm->_snd->_playingSound); - - if (key == 0x4800) - key = 0x0B; - else if (key == 0x5000) - key = 0x0A; - else if (key == 0x4D00) - key = 0x09; - else if (key == 0x4B00) - key = 0x08; - else if (key == 0x011B) - key = 0x1B; - else if (key == 0x0E08) - key = 0x19; - else if (key == 0x5300) - key = 0x1A; - else if ((key & 0xFF) != 0) - key &= 0xFF; - - WRITE_VAR(0, key); - - if (key != 0) - _vm->_util->waitKey(); +void Inter_v2::o2_handleGoblins(OpGobParams ¶ms) { + _vm->_goblin->_gob1NoTurn = (bool) VAR(load16()); + _vm->_goblin->_gob2NoTurn = (bool) VAR(load16()); + _vm->_goblin->_gob1RelaxTimeVar = load16(); + _vm->_goblin->_gob2RelaxTimeVar = load16(); + _vm->_goblin->_gob1Busy = (bool) VAR(load16()); + _vm->_goblin->_gob2Busy = (bool) VAR(load16()); + _vm->_goblin->handleGoblins(); } -void Inter_v2::storeMouse(void) { - int16 x; - int16 y; +int16 Inter_v2::loadSound(int16 search) { + byte *dataPtr; + int16 id; + int16 slot; + uint32 dataSize; + SoundType type; + SoundSource source; + + type = SOUND_SND; + if (!search) { + slot = _vm->_parse->parseValExpr(); + if (slot < 0) { + type = SOUND_ADL; + slot = -slot; + } + id = load16(); + } else { + id = load16(); + + for (slot = 0; slot < 60; slot++) + if (_vm->_game->_soundSamples[slot].isId(id)) + return slot | 0x8000; + + for (slot = 59; slot >= 0; slot--) + if (_vm->_game->_soundSamples[slot].empty()) break; + } + + _vm->_game->freeSoundSlot(slot); + _vm->_game->_soundSamples[slot]._id = id; + + if (id == -1) { + char sndfile[14]; + + source = SOUND_FILE; - x = _vm->_global->_inter_mouseX; - y = _vm->_global->_inter_mouseY; - _vm->_draw->adjustCoords(1, &x, &y); + strcpy(sndfile, _vm->_global->_inter_execPtr); + _vm->_global->_inter_execPtr += 9; - WRITE_VAR(2, x); - WRITE_VAR(3, y); - WRITE_VAR(4, _vm->_game->_mouseButtons); + if (type == SOUND_ADL) + strcat(sndfile, ".ADL"); + else + strcat(sndfile, ".SND"); + + dataPtr = (byte *) _vm->_dataIO->getData(sndfile); + if (dataPtr) + dataSize = _vm->_dataIO->getDataSize(sndfile); + } else if (id >= 30000) { + source = SOUND_EXT; + + dataPtr = (byte *) _vm->_game->loadExtData(id, 0, 0, &dataSize); + } else { + int16 totSize; + + source = SOUND_TOT; + + dataPtr = (byte *) _vm->_game->loadTotResource(id, &totSize); + dataSize = (uint32) ((int32) totSize); + } + + if (dataPtr) { + _vm->_game->_soundSamples[slot].load(type, source, dataPtr, dataSize); + + if ((source == SOUND_EXT) && (type == SOUND_SND)) + if (_vm->_game->_totFileData[0x29] >= 51) + _vm->_game->_soundSamples[slot].flip(); + } + + return slot; } -void Inter_v2::animPalette(void) { +void Inter_v2::animPalette() { int16 i; int16 j; Video::Color col; diff --git a/engines/gob/map.cpp b/engines/gob/map.cpp index 7d366d69a3..3c137d72e9 100644 --- a/engines/gob/map.cpp +++ b/engines/gob/map.cpp @@ -22,24 +22,16 @@ */ #include "common/stdafx.h" -#include "common/endian.h" #include "gob/gob.h" #include "gob/map.h" -#include "gob/video.h" -#include "gob/util.h" -#include "gob/dataio.h" -#include "gob/inter.h" #include "gob/goblin.h" -#include "gob/sound.h" #include "gob/scenery.h" #include "gob/mult.h" namespace Gob { Map::Map(GobEngine *vm) : _vm(vm) { - int i; - _mapWidth = -1; _mapHeight = -1; _screenWidth = 0; @@ -53,7 +45,7 @@ Map::Map(GobEngine *vm) : _vm(vm) { _wayPoints = 0; _bigTiles = false; - for (i = 0; i < 40; i++) { + for (int i = 0; i < 40; i++) { _itemPoses[i].x = 0; _itemPoses[i].y = 0; _itemPoses[i].orient = 0; @@ -65,14 +57,13 @@ Map::Map(GobEngine *vm) : _vm(vm) { _curGoblinY = 0; _destX = 0; _destY = 0; - _loadFromAvo = 0; _sourceFile[0] = 0; - _avoDataPtr = 0; + + _loadFromAvo = false; } Map::~Map() { - if (_passMap) - delete[] _passMap; + delete[] _passMap; if (_itemsMap) { for (int i = 0; i < _mapHeight; i++) @@ -80,15 +71,14 @@ Map::~Map() { delete[] _itemsMap; } - if (_wayPoints) - delete[] _wayPoints; + delete[] _wayPoints; } void Map::placeItem(int16 x, int16 y, int16 id) { - if ((_itemsMap[y][x] & 0xff00) != 0) - _itemsMap[y][x] = (_itemsMap[y][x] & 0xff00) | id; + if ((_itemsMap[y][x] & 0xFF00) != 0) + _itemsMap[y][x] = (_itemsMap[y][x] & 0xFF00) | id; else - _itemsMap[y][x] = (_itemsMap[y][x] & 0x00ff) | (id << 8); + _itemsMap[y][x] = (_itemsMap[y][x] & 0x00FF) | (id << 8); } enum { @@ -101,7 +91,7 @@ enum { int16 Map::getDirection(int16 x0, int16 y0, int16 x1, int16 y1) { int16 dir = 0; - if (x0 == x1 && y0 == y1) + if ((x0 == x1) && (y0 == y1)) return 0; if ((x1 < 0) || (x1 > _mapWidth) || (y1 < 0) || (y1 > _mapHeight)) @@ -117,119 +107,119 @@ int16 Map::getDirection(int16 x0, int16 y0, int16 x1, int16 y1) { else if (x1 < x0) dir |= kLeft; - if (getPass(x0, y0) == 3 && (dir & kUp)) { - if (getPass(x0, y0 - 1) != 0) + if ((getPass(x0, y0) == 3) && (dir & kUp)) { + if ((getPass(x0, y0 - 1) != 0)) return kDirN; } - if (getPass(x0, y0) == 3 && (dir & kDown)) { - if (getPass(x0, y0 + 1) != 0) + if ((getPass(x0, y0) == 3) && (dir & kDown)) { + if ((getPass(x0, y0 + 1) != 0)) return kDirS; } - if (getPass(x0, y0) == 6 && (dir & kUp)) { - if (getPass(x0, y0 - 1) != 0) + if ((getPass(x0, y0) == 6) && (dir & kUp)) { + if ((getPass(x0, y0 - 1) != 0)) return kDirN; } - if (getPass(x0, y0) == 6 && (dir & kDown)) { - if (getPass(x0, y0 + 1) != 0) + if ((getPass(x0, y0) == 6) && (dir & kDown)) { + if ((getPass(x0, y0 + 1) != 0)) return kDirS; } if (dir == kLeft) { - if (x0 - 1 >= 0 && getPass(x0 - 1, y0) != 0) + if (((x0 - 1) >= 0) && (getPass(x0 - 1, y0) != 0)) return kDirW; return 0; } if (dir == kRight) { - if (x0 + 1 < _mapWidth && getPass(x0 + 1, y0) != 0) + if (((x0 + 1) < _mapWidth) && (getPass(x0 + 1, y0) != 0)) return kDirE; return 0; } if (dir == kUp) { - if (y0 - 1 >= 0 && getPass(x0, y0 - 1) != 0) + if (((y0 - 1) >= 0) && (getPass(x0, y0 - 1) != 0)) return kDirN; - if (y0 - 1 >= 0 && x0 - 1 >= 0 - && getPass(x0 - 1, y0 - 1) != 0) + if (((y0 - 1) >= 0) && ((x0 - 1) >= 0) && + (getPass(x0 - 1, y0 - 1) != 0)) return kDirNW; - if (y0 - 1 >= 0 && x0 + 1 < _mapWidth - && getPass(x0 + 1, y0 - 1) != 0) + if (((y0 - 1) >= 0) && ((x0 + 1) < _mapWidth) && + (getPass(x0 + 1, y0 - 1) != 0)) return kDirNE; return 0; } if (dir == kDown) { - if (y0 + 1 < _mapHeight && getPass(x0, y0 + 1) != 0) + if (((y0 + 1) < _mapHeight) && (getPass(x0, y0 + 1) != 0)) return kDirS; - if (y0 + 1 < _mapHeight && x0 - 1 >= 0 - && getPass(x0 - 1, y0 + 1) != 0) + if (((y0 + 1) < _mapHeight) && ((x0 - 1) >= 0) && + (getPass(x0 - 1, y0 + 1) != 0)) return kDirSW; - if (y0 + 1 < _mapHeight && x0 + 1 < _mapWidth - && getPass(x0 + 1, y0 + 1) != 0) + if (((y0 + 1) < _mapHeight) && ((x0 + 1) < _mapWidth) && + (getPass(x0 + 1, y0 + 1) != 0)) return kDirSE; return 0; } if (dir == (kRight | kUp)) { - if (y0 - 1 >= 0 && x0 + 1 < _mapWidth - && getPass(x0 + 1, y0 - 1) != 0) + if (((y0 - 1) >= 0) && ((x0 + 1) < _mapWidth) && + (getPass(x0 + 1, y0 - 1) != 0)) return kDirNE; - if (y0 - 1 >= 0 && getPass(x0, y0 - 1) != 0) + if (((y0 - 1) >= 0) && (getPass(x0, y0 - 1) != 0)) return kDirN; - if (x0 + 1 < _mapWidth && getPass(x0 + 1, y0) != 0) + if (((x0 + 1) < _mapWidth) && (getPass(x0 + 1, y0) != 0)) return kDirE; return 0; } if (dir == (kRight | kDown)) { - if (x0 + 1 < _mapWidth && y0 + 1 < _mapHeight - && getPass(x0 + 1, y0 + 1) != 0) + if (((x0 + 1) < _mapWidth) && ((y0 + 1) < _mapHeight) && + (getPass(x0 + 1, y0 + 1) != 0)) return kDirSE; - if (y0 + 1 < _mapHeight && getPass(x0, y0 + 1) != 0) + if (((y0 + 1) < _mapHeight) && (getPass(x0, y0 + 1) != 0)) return kDirS; - if (x0 + 1 < _mapWidth && getPass(x0 + 1, y0) != 0) + if (((x0 + 1) < _mapWidth) && (getPass(x0 + 1, y0) != 0)) return kDirE; return 0; } if (dir == (kLeft | kUp)) { - if (x0 - 1 >= 0 && y0 - 1 >= 0 - && getPass(x0 - 1, y0 - 1) != 0) + if (((x0 - 1) >= 0) && ((y0 - 1) >= 0) && + (getPass(x0 - 1, y0 - 1) != 0)) return kDirNW; - if (y0 - 1 >= 0 && getPass(x0, y0 - 1) != 0) + if (((y0 - 1) >= 0) && (getPass(x0, y0 - 1) != 0)) return kDirN; - if (x0 - 1 >= 0 && getPass(x0 - 1, y0) != 0) + if (((x0 - 1) >= 0) && (getPass(x0 - 1, y0) != 0)) return kDirW; return 0; } if (dir == (kLeft | kDown)) { - if (x0 - 1 >= 0 && y0 + 1 < _mapHeight - && getPass(x0 - 1, y0 + 1) != 0) + if (((x0 - 1) >= 0) && ((y0 + 1) < _mapHeight) && + (getPass(x0 - 1, y0 + 1) != 0)) return kDirSW; - if (y0 + 1 < _mapHeight && getPass(x0, y0 + 1) != 0) + if (((y0 + 1) < _mapHeight) && (getPass(x0, y0 + 1) != 0)) return kDirS; - if (x0 - 1 >= 0 && getPass(x0 - 1, y0) != 0) + if (((x0 - 1) >= 0) && (getPass(x0 - 1, y0) != 0)) return kDirW; return 0; @@ -240,14 +230,13 @@ int16 Map::getDirection(int16 x0, int16 y0, int16 x1, int16 y1) { int16 Map::findNearestWayPoint(int16 x, int16 y) { int16 nearestWayPoint = -1; int16 length; - int16 i; int16 tmp; length = 30000; - for (i = 0; i < _wayPointsCount; i++) { - if (_wayPoints[i].x < 0 || _wayPoints[i].x >= _mapWidth || - _wayPoints[i].y < 0 || _wayPoints[i].y >= _mapHeight) + for (int i = 0; i < _wayPointsCount; i++) { + if ((_wayPoints[i].x < 0) || (_wayPoints[i].x >= _mapWidth) || + (_wayPoints[i].y < 0) || (_wayPoints[i].y >= _mapHeight)) break; tmp = ABS(x - _wayPoints[i].x) + ABS(y - _wayPoints[i].y); @@ -261,7 +250,74 @@ int16 Map::findNearestWayPoint(int16 x, int16 y) { return nearestWayPoint; } -int16 Map::checkDirectPath(Mult::Mult_Object *obj, int16 x0, int16 y0, int16 x1, int16 y1) { +void Map::findNearestWalkable(int16 &gobDestX, int16 &gobDestY, + int16 mouseX, int16 mouseY) { + int16 mapWidth, mapHeight; + int16 pos1 = -1, pos2 = -1; + int16 distance; + int16 direction; + int i; + + mapWidth = _screenWidth / _tilesWidth; + mapHeight = 200 / _tilesHeight; + direction = 0; + + for (i = 1; i <= gobDestX; i++) + if (getPass(gobDestX - i, gobDestY) != 0) + break; + if (i <= gobDestX) + pos1 = ((i - 1) * _tilesWidth) + (mouseX % _tilesWidth) + 1; + distance = i; + + for (i = 1; (gobDestX + i) < mapWidth; i++) + if (getPass(gobDestX + i, gobDestY) != 0) + break; + if ((gobDestX + i) < mapWidth) + pos2 = (i * _tilesWidth) - (mouseX % _tilesWidth); + + if ((pos2 != -1) && ((pos1 == -1) || (pos1 > pos2))) { + pos1 = pos2; + direction = 1; + distance = i; + } + pos2 = -1; + + for (i = 1; (gobDestY + i) < mapHeight; i++) + if (getPass(gobDestX, gobDestY + i) != 0) + break; + if ((gobDestY + i) < mapHeight) + pos2 = (i * _tilesHeight) - (mouseY % _tilesHeight); + + if ((pos2 != -1) && ((pos1 == -1) || (pos1 > pos2))) { + pos1 = pos2; + direction = 2; + distance = i; + } + pos2 = -1; + + for (i = 1; i <= gobDestY; i++) + if (getPass(gobDestX, gobDestY - i) != 0) + break; + if (i <= gobDestY) + pos2 = ((i - 1) * _tilesHeight) + (mouseY % _tilesHeight) + 1; + + if ((pos2 != -1) && ((pos1 == -1) || (pos1 > pos2))) { + direction = 3; + distance = i; + } + + if (direction == 0) + gobDestX -= distance; + else if (direction == 1) + gobDestX += distance; + else if (direction == 2) + gobDestY += distance; + else if (direction == 3) + gobDestY -= distance; +} + +int16 Map::checkDirectPath(Mult::Mult_Object *obj, + int16 x0, int16 y0, int16 x1, int16 y1) { uint16 dir; while (1) { @@ -269,16 +325,16 @@ int16 Map::checkDirectPath(Mult::Mult_Object *obj, int16 x0, int16 y0, int16 x1, if (obj) { if (obj->nearestWayPoint < obj->nearestDest) { - if (_wayPoints[obj->nearestWayPoint + 1].field_2 == 1) + if (_wayPoints[obj->nearestWayPoint + 1].notWalkable == 1) return 3; } else if (obj->nearestWayPoint > obj->nearestDest) { if (obj->nearestDest > 0) - if (_wayPoints[obj->nearestDest - 1].field_2 == 1) + if (_wayPoints[obj->nearestDest - 1].notWalkable == 1) return 3; } } - if (x0 == x1 && y0 == y1) + if ((x0 == x1) && (y0 == y1)) return 1; if (dir == 0) @@ -324,20 +380,15 @@ int16 Map::checkDirectPath(Mult::Mult_Object *obj, int16 x0, int16 y0, int16 x1, } } -int16 Map::checkLongPath(int16 x0, int16 y0, int16 x1, int16 y1, int16 i0, int16 i1) { - uint16 dir; - int16 curX; - int16 curY; - int16 nextLink; - - curX = x0; - curY = y0; - dir = 0; - - nextLink = 1; +int16 Map::checkLongPath(int16 x0, int16 y0, + int16 x1, int16 y1, int16 i0, int16 i1) { + uint16 dir = 0; + int16 curX = x0; + int16 curY = y0; + int16 nextLink = 1; while (1) { - if (x0 == curX && y0 == curY) + if ((x0 == curX) && (y0 == curY)) nextLink = 1; if (nextLink != 0) { @@ -358,8 +409,8 @@ int16 Map::checkLongPath(int16 x0, int16 y0, int16 x1, int16 y1, int16 i0, int16 curY = _wayPoints[i0].y; } } - if (i0 == i1 && _wayPoints[i0].x == x0 - && _wayPoints[i0].y == y0) { + if ((i0 == i1) && (_wayPoints[i0].x == x0) && + (_wayPoints[i0].y == y0)) { if (checkDirectPath(0, x0, y0, x1, y1) == 1) return 1; return 0; @@ -408,61 +459,26 @@ int16 Map::checkLongPath(int16 x0, int16 y0, int16 x1, int16 y1, int16 i0, int16 } } -void Map::loadDataFromAvo(char *dest, int16 size) { - memcpy(dest, _avoDataPtr, size); - _avoDataPtr += size; -} - -uint16 Map::loadFromAvo_LE_UINT16() { - uint16 tmp = READ_LE_UINT16(_avoDataPtr); - _avoDataPtr += 2; - return tmp; -} - -void Map::loadItemToObject(void) { - int16 flag; - int16 count; - int16 i; - - flag = loadFromAvo_LE_UINT16(); - if (flag == 0) - return; - - _avoDataPtr += 1456; - count = loadFromAvo_LE_UINT16(); - for (i = 0; i < count; i++) { - _avoDataPtr += 20; - _vm->_goblin->_itemToObject[i] = loadFromAvo_LE_UINT16(); - _avoDataPtr += 5; - } -} - void Map::loadMapsInitGobs(void) { int16 layer; - int16 i; - if (_loadFromAvo == 0) + if (!_loadFromAvo) error("load: Loading .pas/.pos files is not supported!"); - for (i = 0; i < 3; i++) { + for (int i = 0; i < 3; i++) _vm->_goblin->nextLayer(_vm->_goblin->_goblins[i]); - } - - for (i = 0; i < 3; i++) { - - layer = - _vm->_goblin->_goblins[i]->stateMach[_vm->_goblin->_goblins[i]->state][0]->layer; - - _vm->_scenery->updateAnim(layer, 0, _vm->_goblin->_goblins[i]->animation, 0, - _vm->_goblin->_goblins[i]->xPos, _vm->_goblin->_goblins[i]->yPos, 0); - - _vm->_goblin->_goblins[i]->yPos = (_vm->_goblin->_gobPositions[i].y + 1) * 6 - - (_vm->_scenery->_toRedrawBottom - _vm->_scenery->_animTop); - - _vm->_goblin->_goblins[i]->xPos = _vm->_goblin->_gobPositions[i].x * 12 - - (_vm->_scenery->_toRedrawLeft - _vm->_scenery->_animLeft); - _vm->_goblin->_goblins[i]->order = _vm->_scenery->_toRedrawBottom / 24 + 3; + for (int i = 0; i < 3; i++) { + Goblin::Gob_Object &gob = *_vm->_goblin->_goblins[i]; + + layer = gob.stateMach[gob.state][0]->layer; + _vm->_scenery->updateAnim(layer, 0, gob.animation, 0, + gob.xPos, gob.yPos, 0); + gob.yPos = (_vm->_goblin->_gobPositions[i].y + 1) * 6 - + (_vm->_scenery->_toRedrawBottom - _vm->_scenery->_animTop); + gob.xPos = _vm->_goblin->_gobPositions[i].x * 12 - + (_vm->_scenery->_toRedrawLeft - _vm->_scenery->_animLeft); + gob.order = _vm->_scenery->_toRedrawBottom / 24 + 3; } _vm->_goblin->_currentGoblin = 0; @@ -475,4 +491,4 @@ void Map::loadMapsInitGobs(void) { _vm->_goblin->_goblins[2]->doAnim = 1; } -} // End of namespace Gob +} // End of namespace Gob diff --git a/engines/gob/map.h b/engines/gob/map.h index 1737c1d601..e9ecb8dd52 100644 --- a/engines/gob/map.h +++ b/engines/gob/map.h @@ -20,10 +20,10 @@ * $Id$ * */ + #ifndef GOB_MAP_H #define GOB_MAP_H -#include "gob/util.h" #include "gob/mult.h" namespace Gob { @@ -36,9 +36,9 @@ public: kDirNW = 0x4700, kDirN = 0x4800, kDirNE = 0x4900, - kDirW = 0x4b00, - kDirE = 0x4d00, - kDirSW = 0x4f00, + kDirW = 0x4B00, + kDirE = 0x4D00, + kDirSW = 0x4F00, kDirS = 0x5000, kDirSE = 0x5100 }; @@ -48,7 +48,7 @@ public: struct Point { int16 x; int16 y; - int16 field_2; // Gob2 + int16 notWalkable; }; #define szMap_ItemPos 3 @@ -56,7 +56,7 @@ public: struct ItemPos { int8 x; int8 y; - int8 orient; // ?? + int8 orient; }; #include "common/pack-end.h" // END STRUCT PACKING @@ -80,18 +80,21 @@ public: int16 _curGoblinY; int16 _destX; int16 _destY; - int8 _loadFromAvo; ItemPos _itemPoses[40]; char _sourceFile[15]; + void findNearestWalkable(int16 &gobDestX, int16 &gobDestY, + int16 mouseX, int16 mouseY); + void placeItem(int16 x, int16 y, int16 id); int16 getDirection(int16 x0, int16 y0, int16 x1, int16 y1); - int16 checkDirectPath(Mult::Mult_Object *obj, int16 x0, int16 y0, int16 x1, int16 y1); - int16 checkLongPath(int16 x0, int16 y0, int16 x1, int16 y1, int16 i0, int16 i1); - void loadItemToObject(void); - void loadDataFromAvo(char *dest, int16 size); + int16 checkDirectPath(Mult::Mult_Object *obj, int16 x0, + int16 y0, int16 x1, int16 y1); + int16 checkLongPath(int16 x0, int16 y0, + int16 x1, int16 y1, int16 i0, int16 i1); + void loadMapsInitGobs(void); virtual int8 getPass(int x, int y, int heightOff = -1) = 0; @@ -107,11 +110,11 @@ public: virtual ~Map(); protected: - char *_avoDataPtr; + bool _loadFromAvo; + GobEngine *_vm; int16 findNearestWayPoint(int16 x, int16 y); - uint16 loadFromAvo_LE_UINT16(); }; class Map_v1 : public Map { @@ -121,17 +124,23 @@ public: virtual void findNearestToDest(Mult::Mult_Object *obj); virtual void optimizePoints(Mult::Mult_Object *obj, int16 x, int16 y); - virtual inline int8 getPass(int x, int y, int heightOff = -1) { + virtual int8 getPass(int x, int y, int heightOff = -1) { return _passMap[y * _mapWidth + x]; } - virtual inline void setPass(int x, int y, int8 pass, int heightOff = -1) { + virtual void setPass(int x, int y, int8 pass, int heightOff = -1) { _passMap[y * _mapWidth + x] = pass; } virtual void init(void); Map_v1(GobEngine *vm); virtual ~Map_v1(); + +protected: + void loadSounds(Common::SeekableReadStream &data); + void loadGoblins(Common::SeekableReadStream &data, uint32 gobsPos); + void loadObjects(Common::SeekableReadStream &data, uint32 objsPos); + void loadItemToObject(Common::SeekableReadStream &data); }; class Map_v2 : public Map_v1 { @@ -141,13 +150,13 @@ public: virtual void findNearestToDest(Mult::Mult_Object *obj); virtual void optimizePoints(Mult::Mult_Object *obj, int16 x, int16 y); - virtual inline int8 getPass(int x, int y, int heightOff = -1) { + virtual int8 getPass(int x, int y, int heightOff = -1) { if (heightOff == -1) heightOff = _passWidth; return _passMap[y * heightOff + x]; } - virtual inline void setPass(int x, int y, int8 pass, int heightOff = -1) { + virtual void setPass(int x, int y, int8 pass, int heightOff = -1) { if (heightOff == -1) heightOff = _passWidth; _passMap[y * heightOff + x] = pass; @@ -156,8 +165,11 @@ public: virtual void init(void); Map_v2(GobEngine *vm); virtual ~Map_v2(); + +protected: + void loadGoblinStates(Common::SeekableReadStream &data, int index); }; -} // End of namespace Gob +} // End of namespace Gob -#endif /* __MAP_H */ +#endif // GOB_MAP_H diff --git a/engines/gob/map_v1.cpp b/engines/gob/map_v1.cpp index 69b2b5f862..8ee5e1174e 100644 --- a/engines/gob/map_v1.cpp +++ b/engines/gob/map_v1.cpp @@ -22,14 +22,13 @@ */ #include "common/stdafx.h" -#include "common/endian.h" +#include "common/stream.h" #include "gob/gob.h" #include "gob/map.h" #include "gob/dataio.h" #include "gob/goblin.h" #include "gob/sound.h" -#include "gob/scenery.h" #include "gob/mult.h" namespace Gob { @@ -41,199 +40,215 @@ Map_v1::~Map_v1() { } void Map_v1::init(void) { - int i; - int j; - _mapWidth = 26; _mapHeight = 28; _passMap = new int8[_mapHeight * _mapWidth]; + memset(_passMap, 0, _mapHeight * _mapWidth * sizeof(int8)); + _itemsMap = new int16*[_mapHeight]; - for (i = 0; i < _mapHeight; i++) { - _itemsMap[i] = new int16[_mapWidth]; - for (j = 0; j < _mapWidth; j++) { - setPass(j, i, 0); - _itemsMap[i][j] = 0; - } - } + for (int i = 0; i < _mapHeight; i++) { + _itemsMap[i] = new int16[_mapWidth]; + memset(_itemsMap[i], 0, _mapWidth * sizeof(int16)); + } _wayPointsCount = 40; _wayPoints = new Point[40]; - for (i = 0; i < 40; i++) { - _wayPoints[i].x = 0; - _wayPoints[i].y = 0; - _wayPoints[i].field_2 = 0; - } + memset(_wayPoints, 0, sizeof(Point)); } void Map_v1::loadMapObjects(char *avjFile) { - int16 i; char avoName[128]; + char *dataBuf; int16 handle; - char item; - int16 soundCount; int16 tmp; - char *savedPtr; - char *savedPtr2; - char *savedPtr3; - int16 state; - int16 col; int32 flag; - Goblin::Gob_State *pState; - char buf[128]; - char sndNames[20][14]; - char *dataBuf; - int16 x; - int16 y; - int16 count2; - int16 count3; + int16 gobDataCount; + int16 objDataCount; + uint32 gobsPos; + uint32 objsPos; strcpy(avoName, _sourceFile); strcat(avoName, ".avo"); - handle = _vm->_dataio->openData(avoName); + handle = _vm->_dataIO->openData(avoName); if (handle >= 0) { - _loadFromAvo = 1; - _vm->_dataio->closeData(handle); - _avoDataPtr = _vm->_dataio->getData(avoName); - dataBuf = _avoDataPtr; - loadDataFromAvo((char *)_passMap, _mapHeight * _mapWidth); - - for (y = 0; y < _mapHeight; y++) { - for (x = 0; x < _mapWidth; x++) { - loadDataFromAvo(&item, 1); - _itemsMap[y][x] = item; - } - } + _loadFromAvo = true; + _vm->_dataIO->closeData(handle); + dataBuf = _vm->_dataIO->getData(avoName); + } else { + _loadFromAvo = false; + dataBuf = _vm->_dataIO->getData(avjFile); + } + Common::MemoryReadStream mapData((byte *) dataBuf, 4294967295U); + + if (_loadFromAvo) { + mapData.read(_passMap, _mapHeight * _mapWidth); + + for (int y = 0; y < _mapHeight; y++) + for (int x = 0; x < _mapWidth; x++) + _itemsMap[y][x] = mapData.readSByte(); - for (i = 0; i < 40; i++) { - _wayPoints[i].x = loadFromAvo_LE_UINT16(); - _wayPoints[i].y = loadFromAvo_LE_UINT16(); + for (int i = 0; i < 40; i++) { + _wayPoints[i].x = mapData.readUint16LE(); + _wayPoints[i].y = mapData.readUint16LE(); } - loadDataFromAvo((char *)_itemPoses, szMap_ItemPos * 20); - } else { - _loadFromAvo = 0; - _avoDataPtr = _vm->_dataio->getData(avjFile); - dataBuf = _avoDataPtr; + mapData.read(_itemPoses, szMap_ItemPos * 20); } - _avoDataPtr += 32; - _avoDataPtr += 76; - _avoDataPtr += 4; - _avoDataPtr += 20; + mapData.skip(32 + 76 + 4 + 20); - for (i = 0; i < 3; i++) { - tmp = loadFromAvo_LE_UINT16(); - _avoDataPtr += tmp * 14; + for (int i = 0; i < 3; i++) { + tmp = mapData.readUint16LE(); + mapData.skip(tmp * 14); } - soundCount = loadFromAvo_LE_UINT16(); - savedPtr = _avoDataPtr; + loadSounds(mapData); - _avoDataPtr += 14 * soundCount; - _avoDataPtr += 4; - _avoDataPtr += 24; + mapData.skip(4 + 24); - count2 = loadFromAvo_LE_UINT16(); - count3 = loadFromAvo_LE_UINT16(); + gobDataCount = mapData.readUint16LE(); + objDataCount = mapData.readUint16LE(); - savedPtr2 = _avoDataPtr; - _avoDataPtr += count2 * 8; + gobsPos = mapData.pos(); + Common::MemoryReadStream gobsData((byte *) dataBuf + gobsPos, 4294967295U); + mapData.skip(gobDataCount * 8); - savedPtr3 = _avoDataPtr; - _avoDataPtr += count3 * 8; + objsPos = mapData.pos(); + Common::MemoryReadStream objsData((byte *) dataBuf + objsPos, 4294967295U); + mapData.skip(objDataCount * 8); - _vm->_goblin->_gobsCount = loadFromAvo_LE_UINT16(); - for (i = 0; i < _vm->_goblin->_gobsCount; i++) { - _vm->_goblin->_goblins[i] = new Goblin::Gob_Object; + loadGoblins(mapData, gobsPos); + loadObjects(mapData, objsPos); - _vm->_goblin->_goblins[i]->xPos = READ_LE_UINT16(savedPtr2); - savedPtr2 += 2; + tmp = mapData.readUint16LE(); + for (int i = 0; i < tmp; i++) { + mapData.skip(30); - _vm->_goblin->_goblins[i]->yPos = READ_LE_UINT16(savedPtr2); - savedPtr2 += 2; + flag = mapData.readSint32LE(); + mapData.skip(56); - _vm->_goblin->_goblins[i]->order = READ_LE_UINT16(savedPtr2); - savedPtr2 += 2; + if (flag != 0) + mapData.skip(30); + } - _vm->_goblin->_goblins[i]->state = READ_LE_UINT16(savedPtr2); - savedPtr2 += 2; + mapData.skip(50); + loadItemToObject(mapData); - if (i == 3) { - _vm->_goblin->_goblins[i]->stateMach = new Goblin::Gob_StateLine[70]; - memset(_vm->_goblin->_goblins[i]->stateMach, 0, 70 * sizeof(Goblin::Gob_StateLine)); - } - else { - _vm->_goblin->_goblins[i]->stateMach = new Goblin::Gob_StateLine[40]; - memset(_vm->_goblin->_goblins[i]->stateMach, 0, 40 * sizeof(Goblin::Gob_StateLine)); - } + delete[] dataBuf; +} - uint32* tempstatedata = new uint32[40*6]; - for (state = 0; state < 40; ++state) { - for (col = 0; col < 6; ++col) { - tempstatedata[state*6+col] = READ_LE_UINT32(_avoDataPtr); - _avoDataPtr += 4; - } - } - _avoDataPtr += 160; - _vm->_goblin->_goblins[i]->multObjIndex = *_avoDataPtr; - _avoDataPtr += 2; - - _vm->_goblin->_goblins[i]->realStateMach = _vm->_goblin->_goblins[i]->stateMach; - for (state = 0; state < 40; state++) { - for (col = 0; col < 6; col++) { - if (tempstatedata[state*6+col] == 0) { +void Map_v1::loadSounds(Common::SeekableReadStream &data) { + int16 count; + int16 handle; + char buf[128]; + char sndNames[20][14]; + + count = data.readUint16LE(); + + for (int i = 0; i < count; i++) { + data.read(buf, 14); + strcat(buf, ".SND"); + strcpy(sndNames[i], buf); + } + + _vm->_snd->loadSample(_vm->_goblin->_soundData[14], "diamant1.snd"); + + for (int i = 0; i < count; i++) { + handle = _vm->_dataIO->openData(sndNames[i]); + if (handle < 0) + continue; + + _vm->_dataIO->closeData(handle); + _vm->_snd->loadSample(_vm->_goblin->_soundData[i], sndNames[i]); + } +} + +void Map_v1::loadGoblins(Common::SeekableReadStream &data, uint32 gobsPos) { + Goblin::Gob_State *pState; + uint32 tmpStateData[40 * 6]; + uint32 tmpPos; + + _vm->_goblin->_gobsCount = data.readUint16LE(); + for (int i = 0; i < _vm->_goblin->_gobsCount; i++) { + int linesCount = (i == 3) ? 70 : 40; + + _vm->_goblin->_goblins[i] = new Goblin::Gob_Object; + memset(_vm->_goblin->_goblins[i], 0, sizeof(Goblin::Gob_Object)); + + tmpPos = data.pos(); + data.seek(gobsPos); + _vm->_goblin->_goblins[i]->xPos = data.readUint16LE(); + _vm->_goblin->_goblins[i]->yPos = data.readUint16LE(); + _vm->_goblin->_goblins[i]->order = data.readUint16LE(); + _vm->_goblin->_goblins[i]->state = data.readUint16LE(); + gobsPos = data.pos(); + data.seek(tmpPos); + + _vm->_goblin->_goblins[i]->stateMach = + new Goblin::Gob_StateLine[linesCount]; + for (int state = 0; state < linesCount; ++state) + for (int col = 0; col < 6; ++col) + _vm->_goblin->_goblins[i]->stateMach[state][col] = 0; + + for (int state = 0; state < 40; ++state) + for (int col = 0; col < 6; ++col) + tmpStateData[state * 6 + col] = data.readUint32LE(); + + data.skip(160); + _vm->_goblin->_goblins[i]->multObjIndex = data.readByte(); + data.skip(1); + + _vm->_goblin->_goblins[i]->realStateMach = + _vm->_goblin->_goblins[i]->stateMach; + for (int state = 0; state < 40; state++) { + for (int col = 0; col < 6; col++) { + if (tmpStateData[state * 6 + col] == 0) { _vm->_goblin->_goblins[i]->stateMach[state][col] = 0; continue; } Goblin::Gob_State *tmpState = new Goblin::Gob_State; + memset(tmpState, 0, sizeof(Goblin::Gob_State)); + _vm->_goblin->_goblins[i]->stateMach[state][col] = tmpState; - tmpState->animation = loadFromAvo_LE_UINT16(); - tmpState->layer = loadFromAvo_LE_UINT16(); - _avoDataPtr += 8; - tmpState->unk0 = loadFromAvo_LE_UINT16(); - tmpState->unk1 = loadFromAvo_LE_UINT16(); - - _avoDataPtr += 2; - if (READ_LE_UINT32(_avoDataPtr) != 0) { - _avoDataPtr += 4; - tmpState->sndItem = loadFromAvo_LE_UINT16(); - } else { - _avoDataPtr += 6; + tmpState->animation = data.readUint16LE(); + tmpState->layer = data.readUint16LE(); + data.skip(8); + tmpState->unk0 = data.readUint16LE(); + tmpState->unk1 = data.readUint16LE(); + + data.skip(2); + if (data.readUint32LE() == 0) { + data.skip(2); tmpState->sndItem = -1; - } - tmpState->freq = loadFromAvo_LE_UINT16(); - tmpState->repCount = loadFromAvo_LE_UINT16(); - tmpState->sndFrame = loadFromAvo_LE_UINT16(); + } else + tmpState->sndItem = data.readUint16LE(); + + tmpState->freq = data.readUint16LE(); + tmpState->repCount = data.readUint16LE(); + tmpState->sndFrame = data.readUint16LE(); } } - delete[] tempstatedata; } pState = new Goblin::Gob_State; + memset(pState, 0, sizeof(Goblin::Gob_State)); _vm->_goblin->_goblins[0]->stateMach[39][0] = pState; - pState->animation = 0; pState->layer = 98; - pState->unk0 = 0; - pState->unk1 = 0; pState->sndItem = -1; pState = new Goblin::Gob_State; + memset(pState, 0, sizeof(Goblin::Gob_State)); _vm->_goblin->_goblins[1]->stateMach[39][0] = pState; - pState->animation = 0; pState->layer = 99; - pState->unk0 = 0; - pState->unk1 = 0; pState->sndItem = -1; pState = new Goblin::Gob_State; + memset(pState, 0, sizeof(Goblin::Gob_State)); _vm->_goblin->_goblins[2]->stateMach[39][0] = pState; - pState->animation = 0; pState->layer = 100; - pState->unk0 = 0; - pState->unk1 = 0; pState->sndItem = -1; _vm->_goblin->_goblins[2]->stateMach[10][0]->sndFrame = 13; @@ -244,151 +259,130 @@ void Map_v1::loadMapObjects(char *avjFile) { _vm->_goblin->_goblins[1]->stateMach[10][0]->sndFrame = 13; _vm->_goblin->_goblins[1]->stateMach[11][0]->sndFrame = 13; - for (state = 40; state < 70; state++) { + for (int state = 40; state < 70; state++) { pState = new Goblin::Gob_State; + memset(pState, 0, sizeof(Goblin::Gob_State)); _vm->_goblin->_goblins[3]->stateMach[state][0] = pState; _vm->_goblin->_goblins[3]->stateMach[state][1] = 0; pState->animation = 9; pState->layer = state - 40; pState->sndItem = -1; - pState->sndFrame = 0; } +} - _vm->_goblin->_objCount = loadFromAvo_LE_UINT16(); - for (i = 0; i < _vm->_goblin->_objCount; i++) { +void Map_v1::loadObjects(Common::SeekableReadStream &data, uint32 objsPos) { + Goblin::Gob_State *pState; + uint32 tmpStateData[40 * 6]; + uint32 tmpPos; + + _vm->_goblin->_objCount = data.readUint16LE(); + for (int i = 0; i < _vm->_goblin->_objCount; i++) { _vm->_goblin->_objects[i] = new Goblin::Gob_Object; + memset(_vm->_goblin->_objects[i], 0, sizeof(Goblin::Gob_Object)); - _vm->_goblin->_objects[i]->xPos = READ_LE_UINT16(savedPtr3); - savedPtr3 += 2; - - _vm->_goblin->_objects[i]->yPos = READ_LE_UINT16(savedPtr3); - savedPtr3 += 2; - - _vm->_goblin->_objects[i]->order = READ_LE_UINT16(savedPtr3); - savedPtr3 += 2; - - _vm->_goblin->_objects[i]->state = READ_LE_UINT16(savedPtr3); - savedPtr3 += 2; + tmpPos = data.pos(); + data.seek(objsPos); + _vm->_goblin->_objects[i]->xPos = data.readUint16LE(); + _vm->_goblin->_objects[i]->yPos = data.readUint16LE(); + _vm->_goblin->_objects[i]->order = data.readUint16LE(); + _vm->_goblin->_objects[i]->state = data.readUint16LE(); + objsPos = data.pos(); + data.seek(tmpPos); _vm->_goblin->_objects[i]->stateMach = new Goblin::Gob_StateLine[40]; - - uint32* tempstatedata = new uint32[40*6]; - for (state = 0; state < 40; ++state) { - for (col = 0; col < 6; ++col) { - tempstatedata[state*6+col] = READ_LE_UINT32(_avoDataPtr); - _avoDataPtr += 4; + for (int state = 0; state < 40; ++state) { + for (int col = 0; col < 6; ++col) { + _vm->_goblin->_objects[i]->stateMach[state][col] = 0; + tmpStateData[state * 6 + col] = data.readUint32LE(); } } - _avoDataPtr += 160; - _vm->_goblin->_objects[i]->multObjIndex = *_avoDataPtr; - _avoDataPtr += 2; - - _vm->_goblin->_objects[i]->realStateMach = _vm->_goblin->_objects[i]->stateMach; - for (state = 0; state < 40; state++) { - for (col = 0; col < 6; col++) { - if (tempstatedata[state*6+col] == 0) { + + data.skip(160); + _vm->_goblin->_objects[i]->multObjIndex = data.readByte(); + data.skip(1); + + _vm->_goblin->_objects[i]->realStateMach = + _vm->_goblin->_objects[i]->stateMach; + for (int state = 0; state < 40; state++) { + for (int col = 0; col < 6; col++) { + if (tmpStateData[state * 6 + col] == 0) { _vm->_goblin->_objects[i]->stateMach[state][col] = 0; continue; } Goblin::Gob_State *tmpState = new Goblin::Gob_State; + memset(tmpState, 0, sizeof(Goblin::Gob_State)); _vm->_goblin->_objects[i]->stateMach[state][col] = tmpState; - tmpState->animation = loadFromAvo_LE_UINT16(); - tmpState->layer = loadFromAvo_LE_UINT16(); - _avoDataPtr += 8; - tmpState->unk0 = loadFromAvo_LE_UINT16(); - tmpState->unk1 = loadFromAvo_LE_UINT16(); - - _avoDataPtr += 2; - if (READ_LE_UINT32(_avoDataPtr) != 0) { - _avoDataPtr += 4; - tmpState->sndItem = loadFromAvo_LE_UINT16(); - } else { - _avoDataPtr += 6; + tmpState->animation = data.readUint16LE(); + tmpState->layer = data.readUint16LE(); + data.skip(8); + tmpState->unk0 = data.readUint16LE(); + tmpState->unk1 = data.readUint16LE(); + + data.skip(2); + if (data.readUint32LE() == 0) { + data.skip(2); tmpState->sndItem = -1; - } - tmpState->freq = loadFromAvo_LE_UINT16(); - tmpState->repCount = loadFromAvo_LE_UINT16(); - tmpState->sndFrame = loadFromAvo_LE_UINT16(); + } else + tmpState->sndItem = data.readUint16LE(); + + tmpState->freq = data.readUint16LE(); + tmpState->repCount = data.readUint16LE(); + tmpState->sndFrame = data.readUint16LE(); } } - delete[] tempstatedata; } _vm->_goblin->_objects[10] = new Goblin::Gob_Object; memset(_vm->_goblin->_objects[10], 0, sizeof(Goblin::Gob_Object)); _vm->_goblin->_objects[10]->stateMach = new Goblin::Gob_StateLine[40]; - for (state = 0; state < 40; ++state) - for (col = 0; col < 6; ++col) + for (int state = 0; state < 40; ++state) + for (int col = 0; col < 6; ++col) _vm->_goblin->_objects[10]->stateMach[state][col] = 0; pState = new Goblin::Gob_State; + memset(pState, 0, sizeof(Goblin::Gob_State)); _vm->_goblin->_objects[10]->stateMach[0][0] = pState; - memset(pState, 0, sizeof(Goblin::Gob_State)); pState->animation = 9; pState->layer = 27; - pState->unk0 = 0; - pState->unk1 = 0; pState->sndItem = -1; - pState->sndFrame = 0; _vm->_goblin->placeObject(_vm->_goblin->_objects[10], 1, 0, 0, 0, 0); - _vm->_goblin->_objects[10]->realStateMach = _vm->_goblin->_objects[10]->stateMach; + _vm->_goblin->_objects[10]->realStateMach = + _vm->_goblin->_objects[10]->stateMach; _vm->_goblin->_objects[10]->type = 1; _vm->_goblin->_objects[10]->unk14 = 1; +} - state = loadFromAvo_LE_UINT16(); - for (i = 0; i < state; i++) { - _avoDataPtr += 30; - - loadDataFromAvo((char *)&flag, 4); - _avoDataPtr += 56; - - if (flag != 0) - _avoDataPtr += 30; - } - - loadDataFromAvo((char *)&tmp, 2); - _avoDataPtr += 48; - loadItemToObject(); - _avoDataPtr = savedPtr; - - for (i = 0; i < soundCount; i++) { - loadDataFromAvo(buf, 14); - strcat(buf, ".SND"); - strcpy(sndNames[i], buf); - } - - delete[] dataBuf; - - _vm->_goblin->_soundData[14] = _vm->_snd->loadSoundData("diamant1.snd"); +void Map_v1::loadItemToObject(Common::SeekableReadStream &data) { + int16 count; - for (i = 0; i < soundCount; i++) { - handle = _vm->_dataio->openData(sndNames[i]); - if (handle < 0) - continue; + if (data.readUint16LE() == 0) + return; - _vm->_dataio->closeData(handle); - _vm->_goblin->_soundData[i] = _vm->_snd->loadSoundData(sndNames[i]); + data.skip(1456); + count = data.readUint16LE(); + for (int i = 0; i < count; i++) { + data.skip(20); + _vm->_goblin->_itemToObject[i] = data.readUint16LE(); + data.skip(5); } } void Map_v1::optimizePoints(Mult::Mult_Object *obj, int16 x, int16 y) { - int16 i; - if (_nearestWayPoint < _nearestDest) { - for (i = _nearestWayPoint; i <= _nearestDest; i++) { + for (int i = _nearestWayPoint; i <= _nearestDest; i++) { if (checkDirectPath(0, _curGoblinX, _curGoblinY, _wayPoints[i].x, _wayPoints[i].y) == 1) _nearestWayPoint = i; } } else if (_nearestWayPoint > _nearestDest) { - for (i = _nearestWayPoint; i >= _nearestDest; i--) { + for (int i = _nearestWayPoint; i >= _nearestDest; i--) { if (checkDirectPath(0, _curGoblinX, _curGoblinY, _wayPoints[i].x, _wayPoints[i].y) == 1) _nearestWayPoint = i; diff --git a/engines/gob/map_v2.cpp b/engines/gob/map_v2.cpp index 0aeae7b598..09842b6e5c 100644 --- a/engines/gob/map_v2.cpp +++ b/engines/gob/map_v2.cpp @@ -22,19 +22,16 @@ */ #include "common/stdafx.h" -#include "common/endian.h" #include "common/stream.h" #include "gob/gob.h" #include "gob/map.h" -#include "gob/dataio.h" +#include "gob/global.h" #include "gob/goblin.h" -#include "gob/sound.h" #include "gob/inter.h" #include "gob/game.h" #include "gob/parse.h" #include "gob/mult.h" -#include "gob/scenery.h" namespace Gob { @@ -49,24 +46,15 @@ void Map_v2::init(void) { } void Map_v2::loadMapObjects(char *avjFile) { - int i; - int j; - int k; uint8 wayPointsCount; int16 var; int16 id; - int16 mapHeight; - int16 mapWidth; + int16 mapWidth, mapHeight; int16 tmp; - int16 numData; - int16 statesCount; - int16 state; char *variables; char *extData; - uint32 dataPos1; - uint32 dataPos2; - int8 statesMask[102]; - Mult::Mult_GobState *statesPtr; + uint32 tmpPos; + uint32 passPos; var = _vm->_parse->parseVarIndex(); variables = _vm->_global->_inter_variables + var; @@ -98,8 +86,8 @@ void Map_v2::loadMapObjects(char *avjFile) { _mapWidth = _screenWidth / _tilesWidth; _mapHeight = 200 / _tilesHeight; - dataPos2 = mapData.pos(); - mapData.seek(_mapWidth * _mapHeight, SEEK_CUR); + passPos = mapData.pos(); + mapData.skip(_mapWidth * _mapHeight); if (*extData == 1) wayPointsCount = _wayPointsCount = 40; @@ -110,15 +98,15 @@ void Map_v2::loadMapObjects(char *avjFile) { delete[] _wayPoints; _wayPoints = new Point[wayPointsCount]; - for (i = 0; i < _wayPointsCount; i++) { + for (int i = 0; i < _wayPointsCount; i++) { _wayPoints[i].x = mapData.readSByte(); _wayPoints[i].y = mapData.readSByte(); - _wayPoints[i].field_2 = mapData.readSByte(); + _wayPoints[i].notWalkable = mapData.readSByte(); } // In the original asm, this writes byte-wise into the variables-array - dataPos1 = mapData.pos(); - mapData.seek(dataPos2); + tmpPos = mapData.pos(); + mapData.seek(passPos); if (variables != _vm->_global->_inter_variables) { byte *sizes; @@ -127,71 +115,88 @@ void Map_v2::loadMapObjects(char *avjFile) { mapWidth = _screenWidth / _tilesWidth; sizes = _vm->_global->_inter_variablesSizes + (((char *) _passMap) - _vm->_global->_inter_variables); - for (i = 0; i < mapHeight; i++) { - for (j = 0; j < mapWidth; j++) + for (int i = 0; i < mapHeight; i++) { + for (int j = 0; j < mapWidth; j++) setPass(j, i, mapData.readSByte()); memset(sizes + i * _passWidth, 0, mapWidth); } } - mapData.seek(dataPos1); + mapData.seek(tmpPos); tmp = mapData.readSint16LE(); - mapData.seek(tmp * 14, SEEK_CUR); + mapData.skip(tmp * 14); tmp = mapData.readSint16LE(); - mapData.seek(tmp * 14 + 28, SEEK_CUR); + mapData.skip(tmp * 14 + 28); tmp = mapData.readSint16LE(); - mapData.seek(tmp * 14, SEEK_CUR); + mapData.skip(tmp * 14); _vm->_goblin->_gobsCount = tmp; - for (i = 0; i < _vm->_goblin->_gobsCount; i++) { - memset(statesMask, -1, 101); - _vm->_mult->_objects[i].goblinStates = new Mult::Mult_GobState*[101]; - memset(_vm->_mult->_objects[i].goblinStates, 0, 101 * sizeof(Mult::Mult_GobState *)); - mapData.read(statesMask, 100); - dataPos1 = mapData.pos(); - statesCount = 0; - for (j = 0; j < 100; j++) { - if (statesMask[j] != -1) { - statesCount++; - mapData.seek(4, SEEK_CUR); - numData = mapData.readByte(); - statesCount += numData; - mapData.seek(numData * 9, SEEK_CUR); - } - } - statesPtr = new Mult::Mult_GobState[statesCount]; - _vm->_mult->_objects[i].goblinStates[0] = statesPtr; - mapData.seek(dataPos1); - for (j = 0; j < 100; j++) { - state = statesMask[j]; - if (state != -1) { - _vm->_mult->_objects[i].goblinStates[state] = statesPtr++; - _vm->_mult->_objects[i].goblinStates[state][0].animation = mapData.readSint16LE(); - _vm->_mult->_objects[i].goblinStates[state][0].layer = mapData.readSint16LE(); - numData = mapData.readByte(); - _vm->_mult->_objects[i].goblinStates[state][0].dataCount = numData; - for (k = 1; k <= numData; k++) { - mapData.seek(1, SEEK_CUR); - _vm->_mult->_objects[i].goblinStates[state][k].sndItem = mapData.readSByte(); - mapData.seek(1, SEEK_CUR); - _vm->_mult->_objects[i].goblinStates[state][k].sndFrame = mapData.readByte(); - mapData.seek(1, SEEK_CUR); - _vm->_mult->_objects[i].goblinStates[state][k].freq = mapData.readSint16LE(); - _vm->_mult->_objects[i].goblinStates[state][k].repCount = mapData.readSByte(); - _vm->_mult->_objects[i].goblinStates[state][k].speaker = mapData.readByte(); - statesPtr++; - } - } - } - } + for (int i = 0; i < _vm->_goblin->_gobsCount; i++) + loadGoblinStates(mapData, i); _vm->_goblin->_soundSlotsCount = _vm->_inter->load16(); - for (i = 0; i < _vm->_goblin->_soundSlotsCount; i++) + for (int i = 0; i < _vm->_goblin->_soundSlotsCount; i++) _vm->_goblin->_soundSlots[i] = _vm->_inter->loadSound(1); delete[] extData; } +void Map_v2::loadGoblinStates(Common::SeekableReadStream &data, int index) { + Mult::Mult_GobState *statesPtr; + Mult::Mult_GobState *gobState; + int8 indices[102]; + uint8 statesCount; + uint8 dataCount; + int16 state; + uint32 tmpPos; + + memset(indices, -1, 101); + _vm->_mult->_objects[index].goblinStates = new Mult::Mult_GobState*[101]; + memset(_vm->_mult->_objects[index].goblinStates, 0, + 101 * sizeof(Mult::Mult_GobState *)); + + data.read(indices, 100); + tmpPos = data.pos(); + statesCount = 0; + for (int i = 0; i < 100; i++) { + if (indices[i] != -1) { + statesCount++; + data.skip(4); + dataCount = data.readByte(); + statesCount += dataCount; + data.skip(dataCount * 9); + } + } + + data.seek(tmpPos); + + statesPtr = new Mult::Mult_GobState[statesCount]; + _vm->_mult->_objects[index].goblinStates[0] = statesPtr; + for (int i = 0; i < 100; i++) { + state = indices[i]; + if (state != -1) { + _vm->_mult->_objects[index].goblinStates[state] = statesPtr++; + gobState = _vm->_mult->_objects[index].goblinStates[state]; + + gobState[0].animation = data.readSint16LE(); + gobState[0].layer = data.readSint16LE(); + dataCount = data.readByte(); + gobState[0].dataCount = dataCount; + for (uint8 j = 1; j <= dataCount; j++) { + data.skip(1); + gobState[j].sndItem = data.readSByte(); + data.skip(1); + gobState[j].sndFrame = data.readByte(); + data.skip(1); + gobState[j].freq = data.readSint16LE(); + gobState[j].repCount = data.readSByte(); + gobState[j].speaker = data.readByte(); + statesPtr++; + } + } + } +} + void Map_v2::findNearestToGob(Mult::Mult_Object *obj) { int16 wayPoint = findNearestWayPoint(obj->goblinX, obj->goblinY); @@ -207,17 +212,14 @@ void Map_v2::findNearestToDest(Mult::Mult_Object *obj) { } void Map_v2::optimizePoints(Mult::Mult_Object *obj, int16 x, int16 y) { - int i; - int16 var_2; - if (obj->nearestWayPoint < obj->nearestDest) { - var_2 = obj->nearestWayPoint; - for (i = obj->nearestWayPoint; i <= obj->nearestDest; i++) { + for (int i = obj->nearestWayPoint; i <= obj->nearestDest; i++) { if (checkDirectPath(obj, x, y, _wayPoints[i].x, _wayPoints[i].y) == 1) obj->nearestWayPoint = i; } } else { - for (i = obj->nearestWayPoint; i >= obj->nearestDest && _wayPoints[i].field_2 != 1; i--) { + for (int i = obj->nearestWayPoint; + i >= obj->nearestDest && (_wayPoints[i].notWalkable != 1); i--) { if (checkDirectPath(obj, x, y, _wayPoints[i].x, _wayPoints[i].y) == 1) obj->nearestWayPoint = i; } diff --git a/engines/gob/module.mk b/engines/gob/module.mk index d1039ba454..5673349a1f 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -1,7 +1,6 @@ MODULE := engines/gob MODULE_OBJS := \ - anim.o \ cdrom.o \ dataio.o \ detection.o \ @@ -18,6 +17,7 @@ MODULE_OBJS := \ goblin.o \ goblin_v1.o \ goblin_v2.o \ + imd.o \ init.o \ init_v1.o \ init_v2.o \ @@ -32,7 +32,6 @@ MODULE_OBJS := \ mult_v1.o \ mult_v2.o \ music.o \ - pack.o \ palanim.o \ parse.o \ parse_v1.o \ @@ -41,7 +40,6 @@ MODULE_OBJS := \ scenery_v1.o \ scenery_v2.o \ sound.o \ - timer.o \ util.o \ video.o \ video_v1.o \ diff --git a/engines/gob/mult.cpp b/engines/gob/mult.cpp index 8991494e7f..2cf94bd84a 100644 --- a/engines/gob/mult.cpp +++ b/engines/gob/mult.cpp @@ -25,50 +25,54 @@ #include "common/endian.h" #include "gob/gob.h" -#include "gob/video.h" -#include "gob/anim.h" -#include "gob/draw.h" -#include "gob/scenery.h" #include "gob/mult.h" -#include "gob/util.h" -#include "gob/inter.h" -#include "gob/parse.h" #include "gob/global.h" -#include "gob/sound.h" -#include "gob/palanim.h" +#include "gob/util.h" +#include "gob/draw.h" #include "gob/game.h" +#include "gob/palanim.h" +#include "gob/scenery.h" +#include "gob/sound.h" +#include "gob/video.h" namespace Gob { Mult::Mult(GobEngine *vm) : _vm(vm) { - int i; - _multData = 0; + + _frame = 0; + + _objCount = 0; _objects = 0; + _renderData = 0; - _renderData2 = 0; - _objCount = 0; - _underAnimSurf = 0; - _frame = 0; - _doPalSubst = 0; + _renderObjs = 0; + + _orderArray = 0; + + _index = 0; _counter = 0; + _animDataAllocated = false; + + for (int i = 0; i < 8; i++) + _multDatas[i] = 0; + + _doPalSubst = false; _animArrayX = 0; _animArrayY = 0; _animArrayData = 0; - _index = 0; - _palKeyIndex = 0; _oldPalette = 0; - _palAnimKey = 0; - for (i = 0; i < 256; i++) { + for (int i = 0; i < 256; i++) { _palAnimPalette[i].red = 0; _palAnimPalette[i].green = 0; _palAnimPalette[i].blue = 0; } - for (i = 0; i < 4; i++) { - _palAnimIndices[i] = 0; + + _palAnimKey = 0; + for (int i = 0; i < 4; i++) { _palAnimRed[i] = 0; _palAnimGreen[i] = 0; _palAnimBlue[i] = 0; @@ -78,77 +82,343 @@ Mult::Mult(GobEngine *vm) : _vm(vm) { _palFadingGreen = 0; _palFadingBlue = 0; - _animDataAllocated = 0; - - for (i = 0; i < 5; i++) - for (int j = 0; j < 16; j++) { - _fadePal[i][j].red = 0; - _fadePal[i][j].green = 0; - _fadePal[i][j].blue = 0; - } - - _orderArray = 0; + _animSurf = 0; + _animLeft = 0; + _animTop = 0; + _animWidth = 0; + _animHeight = 0; } Mult::~Mult() { - if (_objects) - delete[] _objects; - if (_orderArray) - delete[] _orderArray; - if (_renderData) - delete[] _renderData; - if (_renderData2) - delete[] _renderData2; - if (_multData) - delete _multData; - if (_animArrayX) - delete[] _animArrayX; - if (_animArrayY) - delete[] _animArrayY; - if (_animArrayData) - delete[] _animArrayData; + delete[] _objects; + delete[] _orderArray; + delete[] _renderData; + delete[] _renderObjs; + delete[] _animArrayX; + delete[] _animArrayY; + delete[] _animArrayData; + delete _multData; } -void Mult::freeAll(void) { - int16 i; +void Mult::initAll(void) { + _objects = 0; + _animSurf = 0; + _renderData = 0; +} +void Mult::freeAll(void) { freeMult(); - for (i = 0; i < 10; i++) - _vm->_scenery->freeAnim(i); - for (i = 0; i < 10; i++) + for (int i = 0; i < 10; i++) { + _vm->_scenery->freeAnim(i); _vm->_scenery->freeStatic(i); + } + _vm->_scenery->init(); } -void Mult::initAll(void) { - int16 i; +void Mult::freeMult() { + delete[] _objects; + delete[] _renderData; + delete[] _renderObjs; + delete[] _orderArray; _objects = 0; - _vm->_anim->_animSurf = 0; _renderData = 0; + _renderObjs = 0; + _orderArray = 0; - for (i = 0; i < 10; i++) - _vm->_scenery->_animPictCount[i] = 0; + _animSurf = 0; + _vm->_draw->freeSprite(22); +} - for (i = 0; i < 20; i++) { - _vm->_scenery->_spriteRefs[i] = 0; - _vm->_scenery->_spriteResId[i] = -1; +void Mult::checkFreeMult(void) { + if (_multData) + freeMultKeys(); +} + +void Mult::zeroMultData(void) { + _multData = 0; +} + +void Mult::playMult(int16 startFrame, int16 endFrame, char checkEscape, + char handleMouse) { + bool stopNoClear; + bool stop; + + if (!_multData) + return; + + stopNoClear = false; + _frame = startFrame; + if (endFrame == -1) + endFrame = 32767; + + if (_frame == -1) + playMultInit(); + + do { + stop = true; + + if (VAR(58) == 0) { + drawStatics(stop); + drawAnims(stop); + } + + animate(); + if (handleMouse) + _vm->_draw->animateCursor(-1); + else + _vm->_draw->blitInvalidated(); + + if (VAR(58) == 0) + drawText(stop, stopNoClear); + + prepPalAnim(stop); + doPalAnim(); + + doFadeAnim(stop); + doSoundAnim(stop, _frame); + + if (_frame >= endFrame) + stopNoClear = true; + + if (_vm->_snd->_playingSound) + stop = false; + + _vm->_util->processInput(); + if (checkEscape && (_vm->_util->checkKey() == 0x11B)) + stop = true; + + _frame++; + _vm->_util->waitEndFrame(); + } while (!stop && !stopNoClear && !_vm->_quitRequested); + + if (!stopNoClear) { + if (_animDataAllocated) { + delete[] _objects; + delete[] _renderData; + delete[] _renderObjs; + delete[] _animArrayX; + delete[] _animArrayY; + delete[] _animArrayData; + delete[] _orderArray; + + _objects = 0; + _renderObjs = 0; + _renderData = 0; + _animArrayX = 0; + _animArrayY = 0; + _animArrayData = 0; + _orderArray = 0; + + _animSurf = 0; + _vm->_draw->freeSprite(22); + + _animDataAllocated = false; + } + + if (_vm->_snd->_playingSound) + _vm->_snd->stopSound(10); + + WRITE_VAR(57, (uint32) -1); + } else + WRITE_VAR(57, _frame - _multData->frameStart - 1); +} + +void Mult::drawText(bool &stop, bool &stopNoClear) { + char *savedIP; + + int16 cmd; + for (_index = 0; _index < _multData->textKeysCount; _index++) { + if (_multData->textKeys[_index].frame != _frame) + continue; + + cmd = _multData->textKeys[_index].cmd; + if (cmd == 0) { + stop = false; + } else if (cmd == 1) { + stopNoClear = true; + _multData->frameStart = 0; + } else if (cmd == 3) { + stop = false; + savedIP = _vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr = _multData->textKeys[_index].script; + } } +} + +void Mult::prepPalAnim(bool &stop) { + _palKeyIndex = -1; + do { + _palKeyIndex++; + if (_palKeyIndex >= _multData->palKeysCount) + return; + } while (_multData->palKeys[_palKeyIndex].frame != _frame); - for (i = 0; i < 10; i++) - _vm->_scenery->_staticPictCount[i] = -1; + if (_multData->palKeys[_palKeyIndex].cmd == -1) { + stop = false; + _doPalSubst = false; + _vm->_global->_pPaletteDesc->vgaPal = _oldPalette; + _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); + } else { + stop = false; + _doPalSubst = true; + _palAnimKey = _palKeyIndex; - _vm->_scenery->_curStaticLayer = -1; - _vm->_scenery->_curStatic = -1; + _multData->palAnimIndices[0] = 0; + _multData->palAnimIndices[1] = 0; + _multData->palAnimIndices[2] = 0; + _multData->palAnimIndices[3] = 0; + + memcpy((char *)_palAnimPalette, + (char *)_vm->_global->_pPaletteDesc->vgaPal, 768); + _vm->_global->_pPaletteDesc->vgaPal = _palAnimPalette; + } } -void Mult::zeroMultData(void) { - _multData = 0; +void Mult::doPalAnim() { + int16 off; + int16 off2; + Video::Color *palPtr; + Mult_PalKey *palKey; + + if (!_doPalSubst) + return; + + for (_index = 0; _index < 4; _index++) { + palKey = &_multData->palKeys[_palAnimKey]; + + if ((_frame % palKey->rates[_index]) != 0) + continue; + + _palAnimRed[_index] = + _vm->_global->_pPaletteDesc->vgaPal[palKey->subst[0][_index] - 1].red; + _palAnimGreen[_index] = + _vm->_global->_pPaletteDesc->vgaPal[palKey->subst[0][_index] - 1].green; + _palAnimBlue[_index] = + _vm->_global->_pPaletteDesc->vgaPal[palKey->subst[0][_index] - 1].blue; + + while (1) { + off = palKey->subst[(_multData->palAnimIndices[_index] + 1) % 16][_index]; + if (off == 0) { + off = palKey->subst[_multData->palAnimIndices[_index]][_index] - 1; + + _vm->_global->_pPaletteDesc->vgaPal[off].red = _palAnimRed[_index]; + _vm->_global->_pPaletteDesc->vgaPal[off].green = _palAnimGreen[_index]; + _vm->_global->_pPaletteDesc->vgaPal[off].blue = _palAnimBlue[_index]; + } else { + off = palKey->subst[(_multData->palAnimIndices[_index] + 1) % 16][_index] - 1; + off2 = palKey->subst[_multData->palAnimIndices[_index]][_index] - 1; + + _vm->_global->_pPaletteDesc->vgaPal[off2].red = + _vm->_global->_pPaletteDesc->vgaPal[off].red; + _vm->_global->_pPaletteDesc->vgaPal[off2].green = + _vm->_global->_pPaletteDesc->vgaPal[off].green; + _vm->_global->_pPaletteDesc->vgaPal[off2].blue = + _vm->_global->_pPaletteDesc->vgaPal[off].blue; + } + + _multData->palAnimIndices[_index] = (_multData->palAnimIndices[_index] + 1) % 16; + + off = palKey->subst[_multData->palAnimIndices[_index]][_index]; + + if (off == 0) { + _multData->palAnimIndices[_index] = 0; + off = palKey->subst[0][_index] - 1; + + _palAnimRed[_index] = _vm->_global->_pPaletteDesc->vgaPal[off].red; + _palAnimGreen[_index] = _vm->_global->_pPaletteDesc->vgaPal[off].green; + _palAnimBlue[_index] = _vm->_global->_pPaletteDesc->vgaPal[off].blue; + } + if (_multData->palAnimIndices[_index] == 0) + break; + } + } + + if (_vm->_global->_colorCount == 256) { + _vm->_video->waitRetrace(_vm->_global->_videoMode); + + palPtr = _vm->_global->_pPaletteDesc->vgaPal; + for (_counter = 0; _counter < 16; _counter++, palPtr++) + _vm->_video->setPalElem(_counter, palPtr->red, palPtr->green, + palPtr->blue, 0, 0x13); + + palPtr = _vm->_global->_pPaletteDesc->vgaPal; + for (_counter = 0; _counter < 16; _counter++, palPtr++) + _vm->_global->_redPalette[_counter] = palPtr->red; + _vm->_global->_greenPalette[_counter] = palPtr->green; + _vm->_global->_bluePalette[_counter] = palPtr->blue; + + } else + _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); } -void Mult::checkFreeMult(void) { - if (_multData) - freeMultKeys(); +void Mult::doFadeAnim(bool &stop) { + Mult_PalFadeKey *fadeKey; + + for (_index = 0; _index < _multData->palFadeKeysCount; _index++) { + fadeKey = &_multData->palFadeKeys[_index]; + + if (fadeKey->frame != _frame) + continue; + + stop = false; + if (!(fadeKey->flag & 1)) { + if (fadeKey->fade == 0) { + _vm->_global->_pPaletteDesc->vgaPal = + _multData->fadePal[fadeKey->palIndex]; + _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); + } else { + _vm->_global->_pPaletteDesc->vgaPal = + _multData->fadePal[fadeKey->palIndex]; + _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, fadeKey->fade, 0); + } + } else { + _vm->_global->_pPaletteDesc->vgaPal = + _multData->fadePal[fadeKey->palIndex]; + _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, fadeKey->fade, -1); + + _palFadingRed = (fadeKey->flag >> 1) & 1; + _palFadingGreen = (fadeKey->flag >> 2) & 1; + _palFadingBlue = (fadeKey->flag >> 3) & 1; + } + } + + if (_palFadingRed) { + _palFadingRed = !_vm->_palAnim->fadeStep(1); + stop = false; + } + if (_palFadingGreen) { + _palFadingGreen = !_vm->_palAnim->fadeStep(2); + stop = false; + } + if (_palFadingBlue) { + _palFadingBlue = !_vm->_palAnim->fadeStep(3); + stop = false; + } +} + +void Mult::doSoundAnim(bool &stop, int16 frame) { + Mult_SndKey *sndKey; + for (_index = 0; _index < _multData->sndKeysCount; _index++) { + sndKey = &_multData->sndKeys[_index]; + if (sndKey->frame != frame) + continue; + + if (sndKey->cmd != -1) { + if ((sndKey->cmd == 1) || (sndKey->cmd == 4)) { + SoundDesc &sample = _vm->_game->_soundSamples[sndKey->soundIndex]; + + _vm->_snd->stopSound(0); + if (!sample.empty()) + _vm->_snd->playSample(sample, sndKey->repCount, + sndKey->freq, sndKey->fadeLength); + } + } else { + if (_vm->_snd->_playingSound) + _vm->_snd->stopSound(sndKey->fadeLength); + } + } } -} // End of namespace Gob +} // End of namespace Gob diff --git a/engines/gob/mult.h b/engines/gob/mult.h index 0b0f6bcf4c..a2cd92b57b 100644 --- a/engines/gob/mult.h +++ b/engines/gob/mult.h @@ -20,11 +20,10 @@ * $Id$ * */ + #ifndef GOB_MULT_H #define GOB_MULT_H -#include "gob/gob.h" -#include "gob/sound.h" #include "gob/video.h" namespace Gob { @@ -43,25 +42,25 @@ public: int8 isPaused; int8 isStatic; int8 maxTick; - int8 unknown; + int8 maxFrame; int8 newLayer; int8 newAnimation; byte intersected; uint8 newCycle; - int8 state; // New in GOB2 - int8 nextState; // New in GOB2 - int8 field_F; // New in GOB2 - int8 curLookDir; // New in GOB2 - int8 isBusy; // New in GOB2 - int8 pathExistence; // New in GOB2 - int8 field_13; // New in GOB2 - int8 field_14; // New in GOB2 - int8 field_15; // New in GOB2 - int8 field_16; // New in GOB2 - int8 field_17; // New in GOB2 - int8 somethingAnimation; // New in GOB2 - int8 somethingLayer; // New in GOB2 - uint8 somethingFrame; // New in GOB2 + int8 state; + int8 nextState; + int8 newState; + int8 curLookDir; + int8 isBusy; + int8 pathExistence; + int8 destX; + int8 destY; + int8 framesLeft; + int8 stateType; + int8 animTypeBak; + int8 redrawAnimation; + int8 redrawLayer; + uint8 redrawFrame; }; struct Mult_GobState { @@ -84,25 +83,25 @@ public: int16 lastRight; int16 lastTop; int16 lastBottom; - Mult::Mult_GobState **goblinStates; // New in GOB2 - int8 goblinX; // New in GOB2 - int8 goblinY; // New in GOB2 - int8 destX; // New in GOB2 - int8 destY; // New in GOB2 - int8 gobDestX; // New in GOB2 - int8 gobDestY; // New in GOB2 - uint8 nearestWayPoint; // New in GOB2 - uint8 nearestDest; // New in GOB2 - int8 field_22; // New in GOB2 - int8 someFlag; // New in GOB2 - int8 field_24; // New in GOB2 - int8 field_25; // New in GOB2 - int8 field_26; // New in GOB2 - int8 field_27; // New in GOB2 - int16 somethingLeft; // New in GOB2 - int16 somethingTop; // New in GOB2 - int16 somethingRight; // New in GOB2 - int16 somethingBottom; // New in GOB2 + Mult_GobState **goblinStates; + int8 goblinX; + int8 goblinY; + int8 destX; + int8 destY; + int8 gobDestX; + int8 gobDestY; + uint8 nearestWayPoint; + uint8 nearestDest; + int8 field_22; + int8 needRedraw; + int8 field_24; + int8 field_25; + int8 field_26; + int8 field_27; + int16 newLeft; + int16 newTop; + int16 newRight; + int16 newBottom; }; struct Mult_StaticKey { @@ -121,9 +120,8 @@ public: struct Mult_TextKey { int16 frame; int16 cmd; - int16 unknown0[9]; - int16 index; - int16 unknown1[2]; + char unknown[18]; + char script[6]; }; struct Mult_PalKey { @@ -152,15 +150,16 @@ public: int16 soundIndex; }; - struct Mult_SomeKey { + struct Mult_ImdKey { int16 frame; - int16 field_2; + int16 imdFile; int16 field_4; int16 field_6; - int16 field_8; + uint16 flags; int16 field_A; - int16 field_C; - int16 field_E; + int16 lastFrame; + int8 palStart; + int8 palEnd; }; struct Mult_Data { @@ -173,15 +172,15 @@ public: int16 staticKeysCount; Mult_StaticKey *staticKeys; int16 staticIndices[10]; - int16 staticLoaded[10]; - int8 staticCount; + bool staticLoaded[10]; + uint8 staticCount; int16 animKeysCount[4]; Mult_AnimKey *animKeys[4]; int16 animIndices[10]; - int8 animCount; + uint8 animCount; - int16 animLoaded[10]; + bool animLoaded[10]; int16 animKeysFrames[4]; int16 animKeysStartFrames[4]; int16 animKeysStopFrames[4]; @@ -199,16 +198,16 @@ public: int16 frameRate; Video::Color fadePal[5][16]; - int16 field_124[4][4]; - int16 palAnimIndices[4]; // Not sure here + int16 animObjs[4][4]; + int16 palAnimIndices[4]; int16 frameStart; - int16 field_17F[4][4]; + int16 imdKeysIndices[4][4]; - int16 someKeysCount[4]; - Mult_SomeKey *someKeys[4]; - int16 someKeysIndices[4]; - char *somepointer09; // ? + int16 imdKeysCount[4]; + Mult_ImdKey *imdKeys[4]; + int16 imdIndices[4]; + char *imdFiles; char *somepointer10; // ? char *execPtr; }; @@ -218,30 +217,57 @@ public: // Globals Mult_Data *_multData; - Mult_Data *_multDatas[8]; + int16 _frame; + + int16 _objCount; Mult_Object *_objects; + int16 *_renderData; - Mult_Object **_renderData2; - int16 _objCount; - Video::SurfaceDesc *_underAnimSurf; + Mult_Object **_renderObjs; - int16 _frame; - char _doPalSubst; + int8 *_orderArray; + + SurfaceDesc::Ptr _animSurf; + int16 _animLeft; + int16 _animTop; + int16 _animWidth; + int16 _animHeight; + + void initAll(); + void freeAll(); + void checkFreeMult(); + void freeMult(); + void zeroMultData(); + void playMult(int16 startFrame, int16 endFrame, char checkEscape, + char handleMouse); + + virtual void loadMult(int16 resId) = 0; + virtual void freeMultKeys() = 0; + virtual void setMultData(uint16 multindex) = 0; + virtual void multSub(uint16 multindex) = 0; + virtual void animate() = 0; + + Mult(GobEngine *vm); + virtual ~Mult(); + +protected: + int16 _index; int16 _counter; + bool _animDataAllocated; + + Mult_Data *_multDatas[8]; + + bool _doPalSubst; int32 *_animArrayX; int32 *_animArrayY; - Mult_AnimData *_animArrayData; - int16 _index; int16 _palKeyIndex; Video::Color *_oldPalette; - Video::Color _palAnimPalette[256]; int16 _palAnimKey; - int16 _palAnimIndices[4]; int16 _palAnimRed[4]; int16 _palAnimGreen[4]; int16 _palAnimBlue[4]; @@ -250,40 +276,18 @@ public: char _palFadingGreen; char _palFadingBlue; - char _animDataAllocated; - - int8 *_orderArray; - - void zeroMultData(void); - void checkFreeMult(void); - void freeAll(void); - void initAll(void); - - virtual void setMultData(uint16 multindex) = 0; - virtual void multSub(uint16 multindex) = 0; - virtual void loadMult(int16 resId) = 0; - virtual void playMult(int16 startFrame, int16 endFrame, char checkEscape, - char handleMouse) = 0; - virtual void animate(void) = 0; - virtual void playSound(Snd::SoundDesc * soundDesc, int16 repCount, - int16 freq, int16 fadeLength) = 0; - virtual void freeMult(void) = 0; - virtual void freeMultKeys(void) = 0; - - Mult(GobEngine *vm); - virtual ~Mult(); - -protected: - Video::Color _fadePal[5][16]; GobEngine *_vm; - virtual char drawStatics(char stop) = 0; - virtual char drawAnims(char stop) = 0; - virtual void drawText(char *pStop, char *pStopNoClear) = 0; - virtual char prepPalAnim(char stop) = 0; - virtual void doPalAnim(void) = 0; - virtual char doFadeAnim(char stop) = 0; - virtual char doSoundAnim(char stop, int16 frame) = 0; + void drawText(bool &stop, bool &stopNoClear); + void prepPalAnim(bool &stop); + void doPalAnim(); + void doFadeAnim(bool &stop); + void doSoundAnim(bool &stop, int16 frame); + + virtual void playMultInit() = 0; + virtual void drawStatics(bool &stop) = 0; + virtual void drawAnims(bool &stop) = 0; + virtual void newCycleAnim(Mult_Object &animObj) = 0; }; class Mult_v1 : public Mult { @@ -291,25 +295,17 @@ public: Mult_v1(GobEngine *vm); virtual ~Mult_v1() {}; + virtual void loadMult(int16 resId); + virtual void freeMultKeys(); virtual void setMultData(uint16 multindex); virtual void multSub(uint16 multindex); - virtual void loadMult(int16 resId); - virtual void playMult(int16 startFrame, int16 endFrame, char checkEscape, - char handleMouse); - virtual void animate(void); - virtual void playSound(Snd::SoundDesc * soundDesc, int16 repCount, - int16 freq, int16 fadeLength); - virtual void freeMult(void); - virtual void freeMultKeys(void); + virtual void animate(); protected: - virtual char drawStatics(char stop); - virtual char drawAnims(char stop); - virtual void drawText(char *pStop, char *pStopNoClear); - virtual char prepPalAnim(char stop); - virtual void doPalAnim(void); - virtual char doFadeAnim(char stop); - virtual char doSoundAnim(char stop, int16 frame); + virtual void playMultInit(); + virtual void drawStatics(bool &stop); + virtual void drawAnims(bool &stop); + virtual void newCycleAnim(Mult_Object &animObj); }; class Mult_v2 : public Mult_v1 { @@ -317,31 +313,25 @@ public: Mult_v2(GobEngine *vm); virtual ~Mult_v2(); + virtual void loadMult(int16 resId); + virtual void freeMultKeys(); virtual void setMultData(uint16 multindex); virtual void multSub(uint16 multindex); - virtual void loadMult(int16 resId); - virtual void playMult(int16 startFrame, int16 endFrame, char checkEscape, - char handleMouse); - virtual void animate(void); - virtual void playSound(Snd::SoundDesc * soundDesc, int16 repCount, - int16 freq, int16 fadeLength); - virtual void freeMult(void); - virtual void freeMultKeys(void); + virtual void animate(); protected: - virtual char drawStatics(char stop); - virtual char drawAnims(char stop); - virtual void drawText(char *pStop, char *pStopNoClear); - virtual char prepPalAnim(char stop); - virtual void doPalAnim(void); - virtual char doFadeAnim(char stop); - virtual char doSoundAnim(char stop, int16 frame); - - void sub_62DD(int16 index); - void sub_6A35(void); - void sub_10C87(Mult_Object *obj); + virtual void playMultInit(); + virtual void drawStatics(bool &stop); + virtual void drawAnims(bool &stop); + virtual void newCycleAnim(Mult_Object &animObj); + + void loadImds(Common::SeekableReadStream &data); + void playImd(char *imdFile, Mult_ImdKey &key, int16 dir, int16 startFrame); + + void advanceObjects(int16 index); + void advanceAllObjects(); }; -} // End of namespace Gob +} // End of namespace Gob -#endif /* __MULT_H */ +#endif // GOB_MULT_H diff --git a/engines/gob/mult_v1.cpp b/engines/gob/mult_v1.cpp index 70cf861fd4..85f70b1207 100644 --- a/engines/gob/mult_v1.cpp +++ b/engines/gob/mult_v1.cpp @@ -27,13 +27,12 @@ #include "gob/gob.h" #include "gob/mult.h" -#include "gob/game.h" -#include "gob/scenery.h" #include "gob/global.h" -#include "gob/inter.h" -#include "gob/anim.h" +#include "gob/util.h" #include "gob/draw.h" -#include "gob/palanim.h" +#include "gob/game.h" +#include "gob/inter.h" +#include "gob/scenery.h" namespace Gob { @@ -41,74 +40,77 @@ Mult_v1::Mult_v1(GobEngine *vm) : Mult(vm) { } void Mult_v1::loadMult(int16 resId) { - int16 palIndex; - int16 i, j; - char *extData; + uint32 dataSize; + byte *extData; + + debugC(4, kDebugGameFlow, "Loading mult"); _multData = new Mult_Data; memset(_multData, 0, sizeof(Mult_Data)); _multData->sndSlotsCount = 0; _multData->frameStart = 0; - extData = _vm->_game->loadExtData(resId, 0, 0); - Common::MemoryReadStream data((byte *) extData, 4294967295U); + + extData = (byte *) _vm->_game->loadExtData(resId, 0, 0, &dataSize); + Common::MemoryReadStream data(extData, dataSize); _multData->staticCount = data.readSByte() + 1; _multData->animCount = data.readSByte() + 1; - for (i = 0; i < _multData->staticCount; i++, data.seek(14, SEEK_CUR)) { + for (int i = 0; i < 10; i++) { + _multData->staticLoaded[i] = false; + _multData->animLoaded[i] = false; + } + + for (int i = 0; i < _multData->staticCount; i++, data.seek(14, SEEK_CUR)) { _multData->staticIndices[i] = _vm->_scenery->loadStatic(1); if (_multData->staticIndices[i] >= 100) { _multData->staticIndices[i] -= 100; - _multData->staticLoaded[i] = 1; - } else { - _multData->staticLoaded[i] = 0; + _multData->staticLoaded[i] = true; } } - for (i = 0; i < _multData->animCount; i++, data.seek(14, SEEK_CUR)) { + for (int i = 0; i < _multData->animCount; i++, data.seek(14, SEEK_CUR)) { _multData->animIndices[i] = _vm->_scenery->loadAnim(1); if (_multData->animIndices[i] >= 100) { _multData->animIndices[i] -= 100; - _multData->animLoaded[i] = 1; - } else { - _multData->animLoaded[i] = 0; + _multData->animLoaded[i] = true; } } _multData->frameRate = data.readSint16LE(); _multData->staticKeysCount = data.readSint16LE(); _multData->staticKeys = new Mult_StaticKey[_multData->staticKeysCount]; - for (i = 0; i < _multData->staticKeysCount; i++) { + for (int i = 0; i < _multData->staticKeysCount; i++) { _multData->staticKeys[i].frame = data.readSint16LE(); _multData->staticKeys[i].layer = data.readSint16LE(); } - for (j = 0; j < 4; j++) { - _multData->animKeysCount[j] = data.readSint16LE(); - _multData->animKeys[j] = new Mult_AnimKey[_multData->animKeysCount[j]]; - for (i = 0; i < _multData->animKeysCount[j]; i++) { - _multData->animKeys[j][i].frame = data.readSint16LE(); - _multData->animKeys[j][i].layer = data.readSint16LE(); - _multData->animKeys[j][i].posX = data.readSint16LE(); - _multData->animKeys[j][i].posY = data.readSint16LE(); - _multData->animKeys[j][i].order = data.readSint16LE(); + for (int i = 0; i < 4; i++) { + _multData->animKeysCount[i] = data.readSint16LE(); + _multData->animKeys[i] = new Mult_AnimKey[_multData->animKeysCount[i]]; + for (int j = 0; j < _multData->animKeysCount[i]; j++) { + _multData->animKeys[i][j].frame = data.readSint16LE(); + _multData->animKeys[i][j].layer = data.readSint16LE(); + _multData->animKeys[i][j].posX = data.readSint16LE(); + _multData->animKeys[i][j].posY = data.readSint16LE(); + _multData->animKeys[i][j].order = data.readSint16LE(); } } - for (palIndex = 0; palIndex < 5; palIndex++) { - for (i = 0; i < 16; i++) { - _fadePal[palIndex][i].red = data.readByte(); - _fadePal[palIndex][i].green = data.readByte(); - _fadePal[palIndex][i].blue = data.readByte(); + for (int i = 0; i < 5; i++) { + for (int j = 0; j < 16; j++) { + _multData->fadePal[i][j].red = data.readByte(); + _multData->fadePal[i][j].green = data.readByte(); + _multData->fadePal[i][j].blue = data.readByte(); } } _multData->palFadeKeysCount = data.readSint16LE(); _multData->palFadeKeys = new Mult_PalFadeKey[_multData->palFadeKeysCount]; - for (i = 0; i < _multData->palFadeKeysCount; i++) { + for (int i = 0; i < _multData->palFadeKeysCount; i++) { _multData->palFadeKeys[i].frame = data.readSint16LE(); _multData->palFadeKeys[i].fade = data.readSint16LE(); _multData->palFadeKeys[i].palIndex = data.readSint16LE(); @@ -117,7 +119,7 @@ void Mult_v1::loadMult(int16 resId) { _multData->palKeysCount = data.readSint16LE(); _multData->palKeys = new Mult_PalKey[_multData->palKeysCount]; - for (i = 0; i < _multData->palKeysCount; i++) { + for (int i = 0; i < _multData->palKeysCount; i++) { _multData->palKeys[i].frame = data.readSint16LE(); _multData->palKeys[i].cmd = data.readSint16LE(); _multData->palKeys[i].rates[0] = data.readSint16LE(); @@ -131,19 +133,18 @@ void Mult_v1::loadMult(int16 resId) { _multData->textKeysCount = data.readSint16LE(); _multData->textKeys = new Mult_TextKey[_multData->textKeysCount]; - for (i = 0; i < _multData->textKeysCount; i++) { + for (int i = 0; i < _multData->textKeysCount; i++) { _multData->textKeys[i].frame = data.readSint16LE(); _multData->textKeys[i].cmd = data.readSint16LE(); - for (int k = 0; k < 9; ++k) - _multData->textKeys[i].unknown0[k] = data.readSint16LE(); - _multData->textKeys[i].index = data.readSint16LE(); - _multData->textKeys[i].unknown1[0] = data.readSint16LE(); - _multData->textKeys[i].unknown1[1] = data.readSint16LE(); + data.read(_multData->textKeys[i].unknown, 18); + data.read(_multData->textKeys[i].script, 6); } _multData->sndKeysCount = data.readSint16LE(); _multData->sndKeys = new Mult_SndKey[_multData->sndKeysCount]; - for (i = 0; i < _multData->sndKeysCount; i++) { + for (int i = 0; i < _multData->sndKeysCount; i++) { + int j; + _multData->sndKeys[i].frame = data.readSint16LE(); _multData->sndKeys[i].cmd = data.readSint16LE(); _multData->sndKeys[i].freq = data.readSint16LE(); @@ -155,7 +156,8 @@ void Mult_v1::loadMult(int16 resId) { switch (_multData->sndKeys[i].cmd) { case 1: case 4: - _multData->sndKeys[i].resId = READ_LE_UINT16(_vm->_global->_inter_execPtr); + _multData->sndKeys[i].resId = + READ_LE_UINT16(_vm->_global->_inter_execPtr); for (j = 0; j < i; j++) { if (_multData->sndKeys[i].resId == @@ -187,458 +189,253 @@ void Mult_v1::loadMult(int16 resId) { delete[] extData; } -void Mult_v1::setMultData(uint16 multindex) { - error("Switching mults not supported for Gob1"); -} - -void Mult_v1::multSub(uint16 multindex) { - error("Switching mults not supported for Gob1"); -} - -void Mult_v1::playMult(int16 startFrame, int16 endFrame, char checkEscape, - char handleMouse) { - char stopNoClear; - char stop; - Mult_Object *multObj; - Mult_AnimData *animData; - - if (_multData == 0) - return; - - stopNoClear = 0; - _frame = startFrame; - if (endFrame == -1) - endFrame = 32767; - - if (_frame == -1) { - _doPalSubst = 0; - _palFadingRed = 0; - _palFadingGreen = 0; - _palFadingBlue = 0; - - _oldPalette = _vm->_global->_pPaletteDesc->vgaPal; - memcpy((char *)_palAnimPalette, - (char *)_vm->_global->_pPaletteDesc->vgaPal, 768); - - if (_vm->_anim->_animSurf == 0) { - _vm->_util->setFrameRate(_multData->frameRate); - _vm->_anim->_areaTop = 0; - _vm->_anim->_areaLeft = 0; - _vm->_anim->_areaWidth = 320; - _vm->_anim->_areaHeight = 200; - _objCount = 4; - - _objects = new Mult_Object[_objCount]; - memset(_objects, 0, _objCount * sizeof(Mult_Object)); - _renderData = new int16[9 * _objCount]; - memset(_renderData, 0, _objCount * 9 * sizeof(int16)); +void Mult_v1::freeMultKeys() { + for (int i = 0; i < _multData->staticCount; i++) + if (_multData->staticLoaded[i]) + _vm->_scenery->freeStatic(_multData->staticIndices[i]); - _animArrayX = new int32[_objCount]; - _animArrayY = new int32[_objCount]; + for (int i = 0; i < _multData->animCount; i++) + if (_multData->animLoaded[i]) + _vm->_scenery->freeAnim(_multData->animIndices[i]); - _animArrayData = new Mult_AnimData[_objCount]; - memset(_animArrayData, 0, _objCount * sizeof(Mult_AnimData)); + delete[] _multData->staticKeys; - for (_counter = 0; _counter < _objCount; _counter++) { - multObj = &_objects[_counter]; + for (int i = 0; i < 4; i++) + delete[] _multData->animKeys[i]; - multObj->pPosX = (int32 *)&_animArrayX[_counter]; - multObj->pPosY = (int32 *)&_animArrayY[_counter]; + delete[] _multData->palFadeKeys; + delete[] _multData->palKeys; + delete[] _multData->textKeys; - multObj->pAnimData = &_animArrayData[_counter]; + for (int i = 0; i < _multData->sndSlotsCount; i++) + _vm->_game->freeSoundSlot(19 - i); - animData = multObj->pAnimData; - animData->isStatic = 1; + delete[] _multData->sndKeys; - multObj->tick = 0; - multObj->lastLeft = -1; - multObj->lastTop = -1; - multObj->lastRight = -1; - multObj->lastBottom = -1; - } + if (_animDataAllocated) { + delete[] _objects; + delete[] _renderData; + delete[] _animArrayX; + delete[] _animArrayY; + delete[] _animArrayData; - _vm->_anim->_animSurf = - _vm->_video->initSurfDesc(_vm->_global->_videoMode, 320, 200, 0); - _vm->_draw->_spritesArray[22] = _vm->_anim->_animSurf; + _objects = 0; + _renderData = 0; + _animArrayX = 0; + _animArrayY = 0; + _animArrayData = 0; - _vm->_video->drawSprite(_vm->_draw->_backSurface, _vm->_anim->_animSurf, - 0, 0, 319, 199, 0, 0, 0); + _animSurf = 0; + _vm->_draw->freeSprite(22); - _animDataAllocated = 1; - } else - _animDataAllocated = 0; - _frame = 0; + _animDataAllocated = false; } - do { - stop = 1; - - if (VAR(58) == 0) { - stop = drawStatics(stop); - stop = drawAnims(stop); - } - - animate(); - if (handleMouse) { - _vm->_draw->animateCursor(-1); - } else { - _vm->_draw->blitInvalidated(); - } - - if (VAR(58) == 0) { - drawText(&stop, &stopNoClear); - } - - stop = prepPalAnim(stop); - doPalAnim(); + delete _multData; + _multData = 0; +} - stop = doFadeAnim(stop); - stop = doSoundAnim(stop, _frame); +void Mult_v1::setMultData(uint16 multindex) { + error("Switching mults not supported for Gob1"); +} - if (_frame >= endFrame) - stopNoClear = 1; +void Mult_v1::multSub(uint16 multindex) { + error("Switching mults not supported for Gob1"); +} - if (_vm->_snd->_playingSound) - stop = 0; +void Mult_v1::playMultInit() { + _doPalSubst = false; + _palFadingRed = 0; + _palFadingGreen = 0; + _palFadingBlue = 0; - _vm->_util->processInput(); - if (checkEscape && _vm->_util->checkKey() == 0x11b) // Esc - stop = 1; + _oldPalette = _vm->_global->_pPaletteDesc->vgaPal; - _frame++; - _vm->_util->waitEndFrame(); - } while (stop == 0 && stopNoClear == 0 && !_vm->_quitRequested); + if (!_animSurf) { + _vm->_util->setFrameRate(_multData->frameRate); + _animTop = 0; + _animLeft = 0; + _animWidth = 320; + _animHeight = 200; + _objCount = 4; - if (stopNoClear == 0) { - if (_animDataAllocated) { - delete[] _objects; - _objects = 0; + delete[] _objects; + delete[] _renderData; + delete[] _animArrayX; + delete[] _animArrayY; + delete[] _animArrayData; - delete[] _renderData; - _renderData = 0; + _objects = new Mult_Object[_objCount]; + _renderData = new int16[9 * _objCount]; + _animArrayX = new int32[_objCount]; + _animArrayY = new int32[_objCount]; + _animArrayData = new Mult_AnimData[_objCount]; - delete[] _animArrayX; - _animArrayX = 0; + memset(_objects, 0, _objCount * sizeof(Mult_Object)); + memset(_renderData, 0, _objCount * 9 * sizeof(int16)); + memset(_animArrayX, 0, _objCount * sizeof(int32)); + memset(_animArrayY, 0, _objCount * sizeof(int32)); + memset(_animArrayData, 0, _objCount * sizeof(Mult_AnimData)); - delete[] _animArrayY; - _animArrayY = 0; + for (_counter = 0; _counter < _objCount; _counter++) { + Mult_Object &multObj = _objects[_counter]; + Mult_AnimData &animData = _animArrayData[_counter]; - delete[] _animArrayData; - _animArrayData = 0; + multObj.pPosX = (int32 *) &_animArrayX[_counter]; + multObj.pPosY = (int32 *) &_animArrayY[_counter]; + multObj.pAnimData = &animData; - _vm->_video->freeSurfDesc(_vm->_anim->_animSurf); - _vm->_anim->_animSurf = 0; - _vm->_draw->_spritesArray[22] = 0; + animData.isStatic = 1; - _animDataAllocated = 0; + multObj.lastLeft = -1; + multObj.lastTop = -1; + multObj.lastRight = -1; + multObj.lastBottom = -1; } - if (_vm->_snd->_playingSound != 0) - _vm->_snd->stopSound(10); + _animSurf = _vm->_video->initSurfDesc(_vm->_global->_videoMode, + 320, 200, 0); + _vm->_draw->_spritesArray[22] = _animSurf; + + _vm->_video->drawSprite(_vm->_draw->_backSurface, + _animSurf, 0, 0, 319, 199, 0, 0, 0); - WRITE_VAR(57, (uint32)-1); + _animDataAllocated = true; } else - WRITE_VAR(57, _frame - 1 - _multData->frameStart); + _animDataAllocated = false; + + _frame = 0; } -char Mult_v1::drawStatics(char stop) { +void Mult_v1::drawStatics(bool &stop) { if (_multData->staticKeys[_multData->staticKeysCount - 1].frame > _frame) - stop = 0; + stop = false; - for (_counter = 0; _counter < _multData->staticKeysCount; - _counter++) { - if (_multData->staticKeys[_counter].frame != _frame - || _multData->staticKeys[_counter].layer == -1) + for (_counter = 0; _counter < _multData->staticKeysCount; _counter++) { + if ((_multData->staticKeys[_counter].frame != _frame) + || (_multData->staticKeys[_counter].layer == -1)) continue; _vm->_scenery->_curStaticLayer = _multData->staticKeys[_counter].layer; for (_vm->_scenery->_curStatic = 0; _vm->_scenery->_curStaticLayer >= - _vm->_scenery->_statics[_multData->staticIndices[_vm->_scenery->_curStatic]].layersCount; + _vm->_scenery->getStaticLayersCount(_multData->staticIndices[_vm->_scenery->_curStatic]); _vm->_scenery->_curStatic++) { _vm->_scenery->_curStaticLayer -= - _vm->_scenery->_statics[_multData->staticIndices[_vm->_scenery->_curStatic]].layersCount; + _vm->_scenery->getStaticLayersCount(_multData->staticIndices[_vm->_scenery->_curStatic]); } _vm->_scenery->_curStatic = _multData->staticIndices[_vm->_scenery->_curStatic]; _vm->_scenery->renderStatic(_vm->_scenery->_curStatic, _vm->_scenery->_curStaticLayer); - _vm->_video->drawSprite(_vm->_draw->_backSurface, _vm->_anim->_animSurf, + _vm->_video->drawSprite(_vm->_draw->_backSurface, _animSurf, 0, 0, 319, 199, 0, 0, 0); } - return stop; } -char Mult_v1::drawAnims(char stop) { - Mult_AnimKey *key; - Mult_Object *animObj; - int16 i; +void Mult_v1::drawAnims(bool &stop) { int16 count; + int animIndex; for (_index = 0; _index < 4; _index++) { for (_counter = 0; _counter < _multData->animKeysCount[_index]; _counter++) { - key = &_multData->animKeys[_index][_counter]; - animObj = &_objects[_index]; - if (key->frame != _frame) - continue; - - if (key->layer != -1) { - (*animObj->pPosX) = key->posX; - (*animObj->pPosY) = key->posY; - - animObj->pAnimData->frame = 0; - animObj->pAnimData->order = key->order; - animObj->pAnimData->animType = 1; - - animObj->pAnimData->isPaused = 0; - animObj->pAnimData->isStatic = 0; - animObj->pAnimData->maxTick = 0; - animObj->tick = 0; - animObj->pAnimData->layer = key->layer; - - count = - _vm->_scenery->_animations[_multData->animIndices[0]].layersCount; - i = 0; - while (animObj->pAnimData->layer >= count) { - animObj->pAnimData->layer -= count; - i++; - - count = - _vm->_scenery->_animations[_multData->animIndices[i]].layersCount; - } - animObj->pAnimData->animation = _multData->animIndices[i]; - } else { - animObj->pAnimData->isStatic = 1; - } - } - } - return stop; -} - -void Mult_v1::drawText(char *pStop, char *pStopNoClear) { - char *savedIP; + Mult_AnimKey &key = _multData->animKeys[_index][_counter]; + Mult_Object &animObj = _objects[_index]; + Mult_AnimData &animData = *(animObj.pAnimData); - int16 cmd; - for (_index = 0; _index < _multData->textKeysCount; _index++) { - if (_multData->textKeys[_index].frame != _frame) - continue; - - cmd = _multData->textKeys[_index].cmd; - if (cmd == 0) { - *pStop = 0; - } else if (cmd == 1) { - *pStopNoClear = 1; - _multData->frameStart = 0; - } else if (cmd == 3) { - *pStop = 0; - savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = - (char *)(&_multData->textKeys[_index].index); - _vm->_global->_inter_execPtr = savedIP; - } - } -} - -char Mult_v1::prepPalAnim(char stop) { - _palKeyIndex = -1; - do { - _palKeyIndex++; - if (_palKeyIndex >= _multData->palKeysCount) - return stop; - } while (_multData->palKeys[_palKeyIndex].frame != _frame); - - if (_multData->palKeys[_palKeyIndex].cmd == -1) { - stop = 0; - _doPalSubst = 0; - _vm->_global->_pPaletteDesc->vgaPal = _oldPalette; - - memcpy((char *)_palAnimPalette, - (char *)_vm->_global->_pPaletteDesc->vgaPal, 768); - - _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); - } else { - stop = 0; - _doPalSubst = 1; - _palAnimKey = _palKeyIndex; - - _palAnimIndices[0] = 0; - _palAnimIndices[1] = 0; - _palAnimIndices[2] = 0; - _palAnimIndices[3] = 0; - - _vm->_global->_pPaletteDesc->vgaPal = _palAnimPalette; - } - return stop; -} - -void Mult_v1::doPalAnim(void) { - int16 off; - int16 off2; - Video::Color *palPtr; - Mult_PalKey *palKey; - - if (_doPalSubst == 0) - return; - - for (_index = 0; _index < 4; _index++) { - palKey = &_multData->palKeys[_palAnimKey]; - - if ((_frame % palKey->rates[_index]) != 0) - continue; - - _palAnimRed[_index] = - _vm->_global->_pPaletteDesc->vgaPal[palKey->subst[0][_index] - 1].red; - _palAnimGreen[_index] = - _vm->_global->_pPaletteDesc->vgaPal[palKey->subst[0][_index] - 1].green; - _palAnimBlue[_index] = - _vm->_global->_pPaletteDesc->vgaPal[palKey->subst[0][_index] - 1].blue; - - while (1) { - off = palKey->subst[(_palAnimIndices[_index] + 1) % 16][_index]; - if (off == 0) { - off = palKey->subst[_palAnimIndices[_index]][_index] - 1; - - _vm->_global->_pPaletteDesc->vgaPal[off].red = _palAnimRed[_index]; - _vm->_global->_pPaletteDesc->vgaPal[off].green = _palAnimGreen[_index]; - _vm->_global->_pPaletteDesc->vgaPal[off].blue = _palAnimBlue[_index]; - } else { - off = palKey->subst[(_palAnimIndices[_index] + 1) % 16][_index] - 1; - off2 = palKey->subst[_palAnimIndices[_index]][_index] - 1; - - _vm->_global->_pPaletteDesc->vgaPal[off2].red = - _vm->_global->_pPaletteDesc->vgaPal[off].red; - _vm->_global->_pPaletteDesc->vgaPal[off2].green = - _vm->_global->_pPaletteDesc->vgaPal[off].green; - _vm->_global->_pPaletteDesc->vgaPal[off2].blue = - _vm->_global->_pPaletteDesc->vgaPal[off].blue; - } - - _palAnimIndices[_index] = (_palAnimIndices[_index] + 1) % 16; - - off = palKey->subst[_palAnimIndices[_index]][_index]; + if (key.frame != _frame) + continue; - if (off == 0) { - _palAnimIndices[_index] = 0; - off = palKey->subst[0][_index] - 1; + if (key.layer != -1) { + *(animObj.pPosX) = key.posX; + *(animObj.pPosY) = key.posY; - _palAnimRed[_index] = _vm->_global->_pPaletteDesc->vgaPal[off].red; - _palAnimGreen[_index] = _vm->_global->_pPaletteDesc->vgaPal[off].green; - _palAnimBlue[_index] = _vm->_global->_pPaletteDesc->vgaPal[off].blue; - } - if (_palAnimIndices[_index] == 0) - break; - } - } + animData.frame = 0; + animData.order = key.order; + animData.animType = 1; - if (_vm->_global->_colorCount == 256) { - _vm->_video->waitRetrace(_vm->_global->_videoMode); + animData.isPaused = 0; + animData.isStatic = 0; + animData.maxTick = 0; + animObj.tick = 0; + animData.layer = key.layer; - palPtr = _vm->_global->_pPaletteDesc->vgaPal; - for (_counter = 0; _counter < 16; _counter++) { - _vm->_video->setPalElem(_counter, palPtr->red, palPtr->green, - palPtr->blue, 0, 0x13); - palPtr++; - } + int i = 0; + animIndex = _multData->animIndices[i]; + count = _vm->_scenery->getAnimLayersCount(animIndex); + while (animData.layer >= count) { + animData.layer -= count; + animIndex = _multData->animIndices[++i]; - palPtr = _vm->_global->_pPaletteDesc->vgaPal; - for (_counter = 0; _counter < 16; _counter++) { - _vm->_global->_redPalette[_counter] = palPtr->red; - _vm->_global->_greenPalette[_counter] = palPtr->green; - _vm->_global->_bluePalette[_counter] = palPtr->blue; - palPtr++; + count = _vm->_scenery->getAnimLayersCount(animIndex); + } + animData.animation = animIndex; + } else + animData.isStatic = 1; } - } else { - _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); } } -char Mult_v1::doFadeAnim(char stop) { - Mult_PalFadeKey *fadeKey; - - for (_index = 0; _index < _multData->palFadeKeysCount; _index++) { - fadeKey = &_multData->palFadeKeys[_index]; - - if (fadeKey->frame != _frame) - continue; - - stop = 0; - if ((fadeKey->flag & 1) == 0) { - if (fadeKey->fade == 0) { - _vm->_global->_pPaletteDesc->vgaPal = _fadePal[fadeKey->palIndex]; - _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); - } else { - _vm->_global->_pPaletteDesc->vgaPal = _fadePal[fadeKey->palIndex]; - _vm->_palanim->fade(_vm->_global->_pPaletteDesc, fadeKey->fade, 0); - } - } else { - _vm->_global->_pPaletteDesc->vgaPal = _fadePal[fadeKey->palIndex]; - _vm->_palanim->fade(_vm->_global->_pPaletteDesc, fadeKey->fade, -1); +void Mult_v1::newCycleAnim(Mult_Object &animObj) { + Mult_AnimData &animData = *(animObj.pAnimData); + int nAnim = animData.animation; + int nLayer = animData.layer; + Scenery::AnimLayer *animLayer = _vm->_scenery->getAnimLayer(nAnim, nLayer); - _palFadingRed = (fadeKey->flag >> 1) & 1; - _palFadingGreen = (fadeKey->flag >> 2) & 1; - _palFadingBlue = (fadeKey->flag >> 3) & 1; - } - } + animData.frame++; - if (_palFadingRed) { - _palFadingRed = !_vm->_palanim->fadeStep(1); - stop = 0; - } - if (_palFadingGreen) { - _palFadingGreen = !_vm->_palanim->fadeStep(2); - stop = 0; - } - if (_palFadingBlue) { - _palFadingBlue = !_vm->_palanim->fadeStep(3); - stop = 0; + if (animData.frame < animLayer->framesCount) { + animData.newCycle = 0; + return; } - return stop; -} - -char Mult_v1::doSoundAnim(char stop, int16 frame) { - Mult_SndKey *sndKey; - for (_index = 0; _index < _multData->sndKeysCount; _index++) { - sndKey = &_multData->sndKeys[_index]; - if (sndKey->frame != frame) - continue; - if (sndKey->cmd != -1) { - if (sndKey->cmd == 1) { - _vm->_snd->stopSound(0); - stop = 0; - playSound(_vm->_game->_soundSamples[sndKey->soundIndex], - sndKey->repCount, sndKey->freq, sndKey->fadeLength); - - } else if (sndKey->cmd == 4) { - _vm->_snd->stopSound(0); - stop = 0; - playSound(_vm->_game->_soundSamples[sndKey->soundIndex], - sndKey->repCount, sndKey->freq, sndKey->fadeLength); - } - } else { - if (_vm->_snd->_playingSound) - _vm->_snd->stopSound(sndKey->fadeLength); - } + switch (animData.animType) { + case 0: + animData.frame = 0; + break; + + case 1: + animData.frame = 0; + *(animObj.pPosX) += animLayer->animDeltaX; + *(animObj.pPosY) += animLayer->animDeltaY; + break; + + case 2: + animData.frame = 0; + animData.animation = + animData.newAnimation; + animData.layer = + animData.newLayer; + break; + + case 3: + animData.animType = 4; + animData.frame = 0; + break; + + case 5: + animData.isStatic = 1; + animData.frame = 0; + break; + + case 6: + animData.frame--; + animData.isPaused = 1; + break; } - return stop; + animData.newCycle = 1; } -void Mult_v1::animate(void) { +void Mult_v1::animate() { int16 minOrder; int16 maxOrder; - int16 *pCurLefts; - int16 *pCurRights; - int16 *pCurTops; - int16 *pCurBottoms; - int16 *pDirtyLefts; - int16 *pDirtyRights; - int16 *pDirtyTops; - int16 *pDirtyBottoms; + int16 *pCurLefts, *pCurRights, *pCurTops, *pCurBottoms; + int16 *pDirtyLefts, *pDirtyRights, *pDirtyTops, *pDirtyBottoms; int16 *pNeedRedraw; Mult_AnimData *pAnimData; int16 i, j; int16 order; - if (_renderData == 0) + if (!_renderData) return; pDirtyLefts = _renderData; @@ -653,42 +450,38 @@ void Mult_v1::animate(void) { minOrder = 100; maxOrder = 0; - //Find dirty areas + // Find dirty areas for (i = 0; i < _objCount; i++) { + Mult_Object &animObj = _objects[i]; + Mult_AnimData &animData = *(animObj.pAnimData); + pNeedRedraw[i] = 0; pDirtyTops[i] = 1000; pDirtyLefts[i] = 1000; pDirtyBottoms[i] = 1000; pDirtyRights[i] = 1000; - pAnimData = _objects[i].pAnimData; - if (pAnimData->isStatic == 0 && pAnimData->isPaused == 0 && - _objects[i].tick == pAnimData->maxTick) { - if (pAnimData->order < minOrder) - minOrder = pAnimData->order; + if (!animData.isStatic && !animData.isPaused && + (animObj.tick == animData.maxTick)) { + if (animData.order < minOrder) + minOrder = animData.order; - if (pAnimData->order > maxOrder) - maxOrder = pAnimData->order; + if (animData.order > maxOrder) + maxOrder = animData.order; pNeedRedraw[i] = 1; - _vm->_scenery->updateAnim(pAnimData->layer, pAnimData->frame, - pAnimData->animation, 0, - *(_objects[i].pPosX), *(_objects[i].pPosY), - 0); + _vm->_scenery->updateAnim(animData.layer, animData.frame, + animData.animation, 0, *(animObj.pPosX), *(animObj.pPosY), 0); - if (_objects[i].lastLeft != -1) { + if (animObj.lastLeft != -1) { pDirtyLefts[i] = - MIN(_objects[i].lastLeft, - _vm->_scenery->_toRedrawLeft); + MIN(animObj.lastLeft, _vm->_scenery->_toRedrawLeft); pDirtyTops[i] = - MIN(_objects[i].lastTop, - _vm->_scenery->_toRedrawTop); + MIN(animObj.lastTop, _vm->_scenery->_toRedrawTop); pDirtyRights[i] = - MAX(_objects[i].lastRight, - _vm->_scenery->_toRedrawRight); + MAX(animObj.lastRight, _vm->_scenery->_toRedrawRight); pDirtyBottoms[i] = - MAX(_objects[i].lastBottom, - _vm->_scenery->_toRedrawBottom); + MAX(animObj.lastBottom, _vm->_scenery->_toRedrawBottom); } else { pDirtyLefts[i] = _vm->_scenery->_toRedrawLeft; pDirtyTops[i] = _vm->_scenery->_toRedrawTop; @@ -700,37 +493,37 @@ void Mult_v1::animate(void) { pCurTops[i] = _vm->_scenery->_toRedrawTop; pCurBottoms[i] = _vm->_scenery->_toRedrawBottom; } else { - if (_objects[i].lastLeft != -1) { - if (pAnimData->order < minOrder) - minOrder = pAnimData->order; + if (animObj.lastLeft != -1) { + if (animData.order < minOrder) + minOrder = animData.order; - if (pAnimData->order > maxOrder) - maxOrder = pAnimData->order; + if (animData.order > maxOrder) + maxOrder = animData.order; - if (pAnimData->isStatic) + if (animData.isStatic) *pNeedRedraw = 1; - pCurLefts[i] = _objects[i].lastLeft; - pDirtyLefts[i] = _objects[i].lastLeft; + pCurLefts[i] = animObj.lastLeft; + pDirtyLefts[i] = animObj.lastLeft; - pCurTops[i] = _objects[i].lastTop; - pDirtyTops[i] = _objects[i].lastTop; + pCurTops[i] = animObj.lastTop; + pDirtyTops[i] = animObj.lastTop; - pCurRights[i] = _objects[i].lastRight; - pDirtyRights[i] = _objects[i].lastRight; + pCurRights[i] = animObj.lastRight; + pDirtyRights[i] = animObj.lastRight; - pCurBottoms[i] = _objects[i].lastBottom; - pDirtyBottoms[i] = _objects[i].lastBottom; + pCurBottoms[i] = animObj.lastBottom; + pDirtyBottoms[i] = animObj.lastBottom; } } } // Find intersections for (i = 0; i < _objCount; i++) { - pAnimData = _objects[i].pAnimData; - pAnimData->intersected = 200; + Mult_AnimData &animData = *(_objects[i].pAnimData); + animData.intersected = 200; - if (pAnimData->isStatic) + if (animData.isStatic) continue; for (j = 0; j < _objCount; j++) { @@ -752,7 +545,7 @@ void Mult_v1::animate(void) { if (pCurBottoms[j] < pCurTops[i]) continue; - pAnimData->intersected = j; + animData.intersected = j; break; } } @@ -760,13 +553,13 @@ void Mult_v1::animate(void) { // Restore dirty areas for (i = 0; i < _objCount; i++) { - if (pNeedRedraw[i] == 0 || _objects[i].lastLeft == -1) + if ((pNeedRedraw[i] == 0) || (_objects[i].lastLeft == -1)) continue; _vm->_draw->_sourceSurface = 22; _vm->_draw->_destSurface = 21; - _vm->_draw->_spriteLeft = pDirtyLefts[i] - _vm->_anim->_areaLeft; - _vm->_draw->_spriteTop = pDirtyTops[i] - _vm->_anim->_areaTop; + _vm->_draw->_spriteLeft = pDirtyLefts[i] - _animLeft; + _vm->_draw->_spriteTop = pDirtyTops[i] - _animTop; _vm->_draw->_spriteRight = pDirtyRights[i] - pDirtyLefts[i] + 1; _vm->_draw->_spriteBottom = pDirtyBottoms[i] - pDirtyTops[i] + 1; _vm->_draw->_destSpriteX = pDirtyLefts[i]; @@ -779,34 +572,28 @@ void Mult_v1::animate(void) { // Update view for (order = minOrder; order <= maxOrder; order++) { for (i = 0; i < _objCount; i++) { - pAnimData = _objects[i].pAnimData; - if (pAnimData->order != order) + Mult_Object &animObj = _objects[i]; + Mult_AnimData &animData = *(animObj.pAnimData); + + if (animData.order != order) continue; if (pNeedRedraw[i]) { - if (pAnimData->isStatic == 0) { - - _vm->_scenery->updateAnim(pAnimData->layer, - pAnimData->frame, - pAnimData->animation, 2, - *(_objects[i].pPosX), - *(_objects[i].pPosY), 1); + if (!animData.isStatic) { + _vm->_scenery->updateAnim(animData.layer, animData.frame, + animData.animation, 2, *(animObj.pPosX), + *(animObj.pPosY), 1); if (_vm->_scenery->_toRedrawLeft != -12345) { - _objects[i].lastLeft = - _vm->_scenery->_toRedrawLeft; - _objects[i].lastTop = - _vm->_scenery->_toRedrawTop; - _objects[i].lastRight = - _vm->_scenery->_toRedrawRight; - _objects[i].lastBottom = - _vm->_scenery->_toRedrawBottom; - } else { - _objects[i].lastLeft = -1; - } + animObj.lastLeft = _vm->_scenery->_toRedrawLeft; + animObj.lastTop = _vm->_scenery->_toRedrawTop; + animObj.lastRight = _vm->_scenery->_toRedrawRight; + animObj.lastBottom = _vm->_scenery->_toRedrawBottom; + } else + animObj.lastLeft = -1; } _vm->_scenery->updateStatic(order + 1); - } else if (pAnimData->isStatic == 0) { + } else if (!animData.isStatic) { for (j = 0; j < _objCount; j++) { if (pNeedRedraw[j] == 0) continue; @@ -828,11 +615,9 @@ void Mult_v1::animate(void) { _vm->_scenery->_toRedrawTop = pDirtyTops[j]; _vm->_scenery->_toRedrawBottom = pDirtyBottoms[j]; - _vm->_scenery->updateAnim(pAnimData->layer, - pAnimData->frame, - pAnimData->animation, 4, - *(_objects[i].pPosX), - *(_objects[i].pPosY), 1); + _vm->_scenery->updateAnim(animData.layer, animData.frame, + animData.animation, 4, *(animObj.pPosX), + *(animObj.pPosY), 1); _vm->_scenery->updateStatic(order + 1); } @@ -851,136 +636,11 @@ void Mult_v1::animate(void) { if (pAnimData->animType == 4) { pAnimData->isPaused = 1; pAnimData->frame = 0; - } else { - pAnimData->frame++; - if (pAnimData->frame >= - _vm->_scenery->_animations[(int)pAnimData->animation]. - layers[pAnimData->layer].framesCount) { - switch (pAnimData->animType) { - case 0: - pAnimData->frame = 0; - break; - - case 1: - pAnimData->frame = 0; - - *(_objects[i].pPosX) = - *(_objects[i].pPosX) + - _vm->_scenery->_animations[(int)pAnimData->animation].layers[pAnimData->layer].animDeltaX; - - *(_objects[i].pPosY) = - *(_objects[i].pPosY) + - _vm->_scenery->_animations[(int)pAnimData->animation].layers[pAnimData->layer].animDeltaY; - break; - - case 2: - pAnimData->frame = 0; - pAnimData->animation = - pAnimData->newAnimation; - pAnimData->layer = - pAnimData->newLayer; - break; - - case 3: - pAnimData->animType = 4; - pAnimData->frame = 0; - break; - - case 5: - pAnimData->isStatic = 1; - pAnimData->frame = 0; - break; - - case 6: - pAnimData->frame--; - pAnimData->isPaused = 1; - break; - } - pAnimData->newCycle = 1; - } else { - pAnimData->newCycle = 0; - } - } - } else { + } else + newCycleAnim(_objects[i]); + } else _objects[i].tick++; - } } } -void Mult_v1::freeMult(void) { - if ((_vm->_anim->_animSurf != 0) && (_vm->_draw->_spritesArray[22] != 0)) - _vm->_video->freeSurfDesc(_vm->_anim->_animSurf); - - delete[] _objects; - delete[] _renderData; - delete[] _orderArray; - - _objects = 0; - _renderData = 0; - _orderArray = 0; - _vm->_anim->_animSurf = 0; - _vm->_draw->_spritesArray[22] = 0; -} - -void Mult_v1::playSound(Snd::SoundDesc * soundDesc, int16 repCount, int16 freq, - int16 fadeLength) { - _vm->_snd->playSample(soundDesc, repCount, freq, fadeLength); -} - -void Mult_v1::freeMultKeys(void) { - int i; - - for (i = 0; i < _multData->staticCount; i++) { - - if (_multData->staticLoaded[i] != 0) - _vm->_scenery->freeStatic(_multData->staticIndices[i]); - } - - for (i = 0; i < _multData->animCount; i++) { - if (_multData->animLoaded[i] != 0) - _vm->_scenery->freeAnim(_multData->animIndices[i]); - } - - delete[] _multData->staticKeys; - - for (i = 0; i < 4; i++) - delete[] _multData->animKeys[i]; - - delete[] _multData->palFadeKeys; - delete[] _multData->palKeys; - delete[] _multData->textKeys; - - for (i = 0; i < _multData->sndSlotsCount; i++) { - _vm->_game->freeSoundSlot(19 - i); - } - - delete[] _multData->sndKeys; - - if (_animDataAllocated != 0) { - delete[] _objects; - _objects = 0; - - delete[] _renderData; - _renderData = 0; - - delete[] _animArrayX; - _animArrayX = 0; - - delete[] _animArrayY; - _animArrayY = 0; - - delete[] _animArrayData; - _animArrayData = 0; - - _vm->_video->freeSurfDesc(_vm->_anim->_animSurf); - _vm->_anim->_animSurf = 0; - _vm->_draw->_spritesArray[22] = 0; - - _animDataAllocated = 0; - } - - delete _multData; - _multData = 0; -} - } // End of namespace Gob diff --git a/engines/gob/mult_v2.cpp b/engines/gob/mult_v2.cpp index 7c1a2ec392..20fa5d4ae0 100644 --- a/engines/gob/mult_v2.cpp +++ b/engines/gob/mult_v2.cpp @@ -27,25 +27,24 @@ #include "gob/gob.h" #include "gob/mult.h" -#include "gob/game.h" -#include "gob/scenery.h" #include "gob/global.h" -#include "gob/inter.h" -#include "gob/anim.h" +#include "gob/util.h" #include "gob/draw.h" -#include "gob/palanim.h" +#include "gob/game.h" +#include "gob/goblin.h" +#include "gob/imd.h" +#include "gob/inter.h" #include "gob/parse.h" -#include "gob/music.h" -#include "gob/map.h" +#include "gob/scenery.h" +#include "gob/video.h" namespace Gob { Mult_v2::Mult_v2(GobEngine *vm) : Mult_v1(vm) { - int i; - - _renderData2 = 0; + _renderObjs = 0; _multData = 0; - for (i = 0; i < 8; i++) _multDatas[i] = 0; + for (int i = 0; i < 8; i++) + _multDatas[i] = 0; } Mult_v2::~Mult_v2() { @@ -57,87 +56,87 @@ Mult_v2::~Mult_v2() { } void Mult_v2::loadMult(int16 resId) { - int16 i, j; int8 index; - char staticCount; - char animCount; - char *extData; - bool hbstaticCount; - int16 palIndex; - int16 size; + uint8 staticCount; + uint8 animCount; + uint32 dataSize; + byte *extData; + bool hasImds; index = (resId & 0x8000) ? *_vm->_global->_inter_execPtr++ : 0; + debugC(4, kDebugGameFlow, "Loading mult %d", index); + _multData = new Mult_Data; memset(_multData, 0, sizeof(Mult_Data)); _multDatas[index] = _multData; - for (i = 0; i < 10; i++) { - _multData->staticLoaded[i] = 0; - _multData->animLoaded[i] = 0; - } - - for (i = 0; i < 4; i++) - _multData->field_124[0][i] = i; + for (int i = 0; i < 4; i++) + _multData->animObjs[0][i] = i; _multData->sndSlotsCount = 0; _multData->frameStart = 0; - extData = _vm->_game->loadExtData(resId, 0, 0); - Common::MemoryReadStream data((byte *) extData, 4294967295U); + extData = (byte *) _vm->_game->loadExtData(resId, 0, 0, &dataSize); + Common::MemoryReadStream data(extData, dataSize); _multData->staticCount = staticCount = data.readSByte(); _multData->animCount = animCount = data.readSByte(); staticCount++; animCount++; - hbstaticCount = (staticCount & 0x80) != 0; + hasImds = (staticCount & 0x80) != 0; staticCount &= 0x7F; - debugC(7, kDebugGraphics, "statics: %u, anims: %u, hb: %u", staticCount, animCount, hbstaticCount); - for (i = 0; i < staticCount; i++, data.seek(14, SEEK_CUR)) { + debugC(7, kDebugGraphics, "statics: %u, anims: %u, imds: %u", + staticCount, animCount, hasImds); + + for (int i = 0; i < 10; i++) { + _multData->staticLoaded[i] = false; + _multData->animLoaded[i] = false; + } + + for (int i = 0; i < staticCount; i++, data.seek(14, SEEK_CUR)) { _multData->staticIndices[i] = _vm->_scenery->loadStatic(1); if (_multData->staticIndices[i] >= 100) { _multData->staticIndices[i] -= 100; - _multData->staticLoaded[i] = 1; - } else - _multData->staticLoaded[i] = 0; + _multData->staticLoaded[i] = true; + } } - for (i = 0; i < animCount; i++, data.seek(14, SEEK_CUR)) { + for (int i = 0; i < animCount; i++, data.seek(14, SEEK_CUR)) { _multData->animIndices[i] = _vm->_scenery->loadAnim(1); if (_multData->animIndices[i] >= 100) { _multData->animIndices[i] -= 100; - _multData->animLoaded[i] = 1; - } else - _multData->animLoaded[i] = 0; + _multData->animLoaded[i] = true; + } } _multData->frameRate = data.readSint16LE(); _multData->staticKeysCount = data.readSint16LE(); _multData->staticKeys = new Mult_StaticKey[_multData->staticKeysCount]; - for (i = 0; i < _multData->staticKeysCount; i++) { + for (int i = 0; i < _multData->staticKeysCount; i++) { _multData->staticKeys[i].frame = data.readSint16LE(); _multData->staticKeys[i].layer = data.readSint16LE(); } - for (i = 0; i < 4; i++) { - _multData->someKeysCount[i] = 0; - _multData->someKeys[i] = 0; - _multData->someKeysIndices[i] = -1; + for (int i = 0; i < 4; i++) { + _multData->imdKeysCount[i] = 0; + _multData->imdKeys[i] = 0; + _multData->imdIndices[i] = -1; - for (j = 0; j < 4; j++) { + for (int j = 0; j < 4; j++) { _multData->animKeysIndices[i][j] = 0; - _multData->field_17F[i][j] = 0; + _multData->imdKeysIndices[i][j] = 0; } _multData->animKeysFrames[i] = -1; _multData->animKeysCount[i] = data.readSint16LE(); _multData->animKeys[i] = new Mult_AnimKey[_multData->animKeysCount[i]]; - for (j = 0; j < _multData->animKeysCount[i]; j++) { + for (int j = 0; j < _multData->animKeysCount[i]; j++) { _multData->animKeys[i][j].frame = data.readSint16LE(); _multData->animKeys[i][j].layer = data.readSint16LE(); _multData->animKeys[i][j].posX = data.readSint16LE(); @@ -146,17 +145,17 @@ void Mult_v2::loadMult(int16 resId) { } } - for (palIndex = 0; palIndex < 5; palIndex++) { - for (i = 0; i < 16; i++) { - _multData->fadePal[palIndex][i].red = data.readByte(); - _multData->fadePal[palIndex][i].green = data.readByte(); - _multData->fadePal[palIndex][i].blue = data.readByte(); + for (int i = 0; i < 5; i++) { + for (int j = 0; j < 16; j++) { + _multData->fadePal[i][j].red = data.readByte(); + _multData->fadePal[i][j].green = data.readByte(); + _multData->fadePal[i][j].blue = data.readByte(); } } _multData->palFadeKeysCount = data.readSint16LE(); _multData->palFadeKeys = new Mult_PalFadeKey[_multData->palFadeKeysCount]; - for (i = 0; i < _multData->palFadeKeysCount; i++) { + for (int i = 0; i < _multData->palFadeKeysCount; i++) { _multData->palFadeKeys[i].frame = data.readSint16LE(); _multData->palFadeKeys[i].fade = data.readSint16LE(); _multData->palFadeKeys[i].palIndex = data.readSint16LE(); @@ -165,7 +164,7 @@ void Mult_v2::loadMult(int16 resId) { _multData->palKeysCount = data.readSint16LE(); _multData->palKeys = new Mult_PalKey[_multData->palKeysCount]; - for (i = 0; i < _multData->palKeysCount; i++) { + for (int i = 0; i < _multData->palKeysCount; i++) { _multData->palKeys[i].frame = data.readSint16LE(); _multData->palKeys[i].cmd = data.readSint16LE(); _multData->palKeys[i].rates[0] = data.readSint16LE(); @@ -179,17 +178,18 @@ void Mult_v2::loadMult(int16 resId) { _multData->textKeysCount = data.readSint16LE(); _multData->textKeys = new Mult_TextKey[_multData->textKeysCount]; - for (i = 0; i < _multData->textKeysCount; i++) { + for (int i = 0; i < _multData->textKeysCount; i++) { _multData->textKeys[i].frame = data.readSint16LE(); _multData->textKeys[i].cmd = data.readSint16LE(); - if (!hbstaticCount) + if (!hasImds) data.seek(24, SEEK_CUR); } _multData->sndKeysCount = data.readSint16LE(); - warning("SoundKeyCount: %d", _multData->sndKeysCount); _multData->sndKeys = new Mult_SndKey[_multData->sndKeysCount]; - for (i = 0; i < _multData->sndKeysCount; i++) { + for (int i = 0; i < _multData->sndKeysCount; i++) { + int j; + _multData->sndKeys[i].frame = data.readSint16LE(); _multData->sndKeys[i].cmd = data.readSint16LE(); _multData->sndKeys[i].freq = data.readSint16LE(); @@ -198,23 +198,28 @@ void Mult_v2::loadMult(int16 resId) { _multData->sndKeys[i].soundIndex = -1; _multData->sndKeys[i].resId = -1; data.seek(2, SEEK_CUR); - if (!hbstaticCount) + if (!hasImds) data.seek(24, SEEK_CUR); switch (_multData->sndKeys[i].cmd) { case 1: case 4: - _multData->sndKeys[i].resId = READ_LE_UINT16(_vm->_global->_inter_execPtr); - for (j = 0; j < i; j++) { // loc_7071 - if (_multData->sndKeys[j].resId == _multData->sndKeys[i].resId) { - _multData->sndKeys[i].soundIndex = _multData->sndKeys[j].soundIndex; + _multData->sndKeys[i].resId = + READ_LE_UINT16(_vm->_global->_inter_execPtr); + for (j = 0; j < i; j++) { + if (_multData->sndKeys[j].resId == + _multData->sndKeys[i].resId) { + _multData->sndKeys[i].soundIndex = + _multData->sndKeys[j].soundIndex; _vm->_global->_inter_execPtr += 2; break; } } if (i == j) { - _multData->sndSlot[_multData->sndSlotsCount] = _vm->_inter->loadSound(1); - _multData->sndKeys[i].soundIndex = _multData->sndSlot[_multData->sndSlotsCount] & 0x7FFF; + _multData->sndSlot[_multData->sndSlotsCount] = + _vm->_inter->loadSound(1); + _multData->sndKeys[i].soundIndex = + _multData->sndSlot[_multData->sndSlotsCount] & 0x7FFF; _multData->sndSlotsCount++; } break; @@ -224,44 +229,111 @@ void Mult_v2::loadMult(int16 resId) { } } - _multData->somepointer09 = 0; + _multData->imdFiles = 0; _multData->somepointer10 = 0; - if (hbstaticCount) { - warning("GOB2 Stub! Mult_Data.somepointer09, Mult_Data.somepointer10"); - size = _vm->_inter->load16(); - _multData->execPtr = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += size * 2; - if (_vm->_game->_totFileData[0x29] >= 51) { - size = data.readSint16LE(); - _multData->somepointer10 = new char[size * 20]; - // According to the original asm, these bytes are written into _multData->somepointer09! - data.read(_multData->somepointer10, size * 20); - size = _vm->_inter->load16(); - if (size > 0) { - _multData->somepointer09 = new char[size * 14]; - memcpy(_multData->somepointer09, _vm->_global->_inter_execPtr, size * 14); - _vm->_global->_inter_execPtr += size * 14; - data.seek(2, SEEK_CUR); - for (i = 0; i < 4; i++) { - _multData->someKeysCount[i] = data.readSint16LE(); - _multData->someKeys[i] = new Mult_SomeKey[_multData->someKeysCount[i]]; - for (j = 0; j < _multData->someKeysCount[i]; j++) { - _multData->someKeys[i][j].frame = data.readSint16LE(); - _multData->someKeys[i][j].field_2 = data.readSint16LE(); - _multData->someKeys[i][j].field_4 = data.readSint16LE(); - _multData->someKeys[i][j].field_6 = data.readSint16LE(); - _multData->someKeys[i][j].field_8 = data.readSint16LE(); - _multData->someKeys[i][j].field_A = data.readSint16LE(); - _multData->someKeys[i][j].field_C = data.readSint16LE(); - _multData->someKeys[i][j].field_E = data.readSint16LE(); - } - } - } + if (hasImds) + loadImds(data); + + delete[] extData; +} + +void Mult_v2::loadImds(Common::SeekableReadStream &data) { + int16 size; + + size = _vm->_inter->load16(); + _multData->execPtr = _vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr += size * 2; + + if (_vm->_game->_totFileData[0x29] < 51) + return; + + size = data.readSint16LE(); + _multData->somepointer10 = new char[size * 20]; + data.read(_multData->somepointer10, size * 20); + size = _vm->_inter->load16(); + if (size <= 0) + return; + + _multData->imdFiles = new char[size * 14]; + memcpy(_multData->imdFiles, _vm->_global->_inter_execPtr, size * 14); + _vm->_global->_inter_execPtr += size * 14; + data.seek(2, SEEK_CUR); + for (int i = 0; i < 4; i++) { + _multData->imdKeysCount[i] = data.readSint16LE(); + _multData->imdKeys[i] = new Mult_ImdKey[_multData->imdKeysCount[i]]; + for (int j = 0; j < _multData->imdKeysCount[i]; j++) { + _multData->imdKeys[i][j].frame = data.readSint16LE(); + _multData->imdKeys[i][j].imdFile = data.readSint16LE(); + _multData->imdKeys[i][j].field_4 = data.readSint16LE(); + _multData->imdKeys[i][j].field_6 = data.readSint16LE(); + _multData->imdKeys[i][j].flags = data.readUint16LE(); + _multData->imdKeys[i][j].field_A = data.readSint16LE(); + _multData->imdKeys[i][j].lastFrame = data.readSint16LE(); + _multData->imdKeys[i][j].palStart = data.readSByte(); + _multData->imdKeys[i][j].palEnd = data.readSByte(); } } +} - delete[] extData; +void Mult_v2::freeMultKeys() { + uint8 animCount; + uint8 staticCount; + + if (!_multData) + return; + + staticCount = (_multData->staticCount + 1) & 0x7F; + animCount = _multData->animCount + 1; + + for (int i = 0; i < staticCount; i++) + if (_multData->staticLoaded[i]) + _vm->_scenery->freeStatic(_multData->staticIndices[i]); + + for (int i = 0; i < animCount; i++) + if (_multData->animLoaded[i]) + _vm->_scenery->freeAnim(_multData->animIndices[i]); + + delete[] _multData->staticKeys; + + for (int i = 0; i < 4; i++) { + delete[] _multData->animKeys[i]; + delete[] _multData->imdKeys[i]; + } + + delete[] _multData->palFadeKeys; + delete[] _multData->palKeys; + delete[] _multData->textKeys; + + for (int i = 0; i < _multData->sndSlotsCount; i++) + if (!(_multData->sndSlot[i] & 0x8000)) + _vm->_game->freeSoundSlot(_multData->sndSlot[i]); + + delete[] _multData->sndKeys; + + delete[] _multData->imdFiles; + delete[] _multData->somepointer10; + + if (_animDataAllocated) { + freeMult(); + + delete[] _animArrayX; + delete[] _animArrayY; + delete[] _animArrayData; + + _animArrayX = 0; + _animArrayY = 0; + _animArrayData = 0; + + _animDataAllocated = false; + } + + for (int i = 0; i < 8; i++) + if (_multDatas[i] == _multData) + _multDatas[i] = 0; + + delete _multData; + _multData = 0; } void Mult_v2::setMultData(uint16 multindex) { @@ -275,10 +347,8 @@ void Mult_v2::setMultData(uint16 multindex) { void Mult_v2::multSub(uint16 multindex) { uint16 flags; int16 expr; - int16 textFrame; - int16 index; // di - int i; - int j; + int16 index; + int16 startFrame, stopFrame, firstFrame; flags = multindex; multindex = (multindex >> 12) & 0xF; @@ -289,7 +359,7 @@ void Mult_v2::multSub(uint16 multindex) { debugC(4, kDebugGameFlow, "Sub mult %d", multindex); _multData = _multDatas[multindex]; - if (_multData == 0) { + if (!_multData) { _vm->_parse->parseValExpr(); _vm->_parse->parseValExpr(); _vm->_parse->parseValExpr(); @@ -314,9 +384,9 @@ void Mult_v2::multSub(uint16 multindex) { flags &= 0x7F; } - _multData->field_124[index][0] = flags; - for (i = 1; i < 4; i++) - _multData->field_124[index][i] = _vm->_parse->parseValExpr(); + _multData->animObjs[index][0] = flags; + for (int i = 1; i < 4; i++) + _multData->animObjs[index][i] = _vm->_parse->parseValExpr(); expr = _vm->_parse->parseValExpr(); _multData->animKeysFrames[index] = expr; @@ -324,842 +394,523 @@ void Mult_v2::multSub(uint16 multindex) { WRITE_VAR(18 + index, expr); if (expr == -1) { - if (_objects) - for (i = 0; i < 4; i++) - if ((_multData->field_124[index][i] != -1) && (_multData->field_124[index][i] != 1024)) - _objects[_multData->field_124[index][i]].pAnimData->animType = - _objects[_multData->field_124[index][i]].pAnimData->field_17; - } else { - if (_multData->animDirection == 1) { - _multData->animKeysStopFrames[index] = 32000; - for (i = 0; i < _multData->textKeysCount; i++) { - textFrame = _multData->textKeys[i].frame; - if ((textFrame > _multData->animKeysStartFrames[index]) && - (textFrame < _multData->animKeysStopFrames[index])) { - _multData->animKeysStopFrames[index] = textFrame; - } - } - } else { - _multData->animKeysStopFrames[index] = 0; - for (i = 0; i < _multData->textKeysCount; i++) { - textFrame = _multData->textKeys[i].frame; - if ((textFrame < _multData->animKeysStartFrames[index]) && - (textFrame > _multData->animKeysStopFrames[index])) { - _multData->animKeysStopFrames[index] = textFrame; - } - } - } - if (_objects) { - for (i = 0; i < 4; i++) { - if ((_multData->field_124[index][i] != -1) && (_multData->field_124[index][i] != 1024)) - _objects[_multData->field_124[index][i]].pAnimData->field_17 = - _objects[_multData->field_124[index][i]].pAnimData->animType; - } - } + if (!_objects) + return; - for (i = 0; i < 4; i++) { - _multData->animKeysIndices[index][i] = 0; - for (j = 0; j < _multData->animKeysCount[i]; j++) { - if (_multData->animKeys[i][j].frame == _multData->animKeysStartFrames[index]) - _multData->animKeysIndices[index][i] = j; - } - } + for (int i = 0; i < 4; i++) { + int obj = _multData->animObjs[index][i]; - if (_multData->animDirection == -1) { // loc_60CF - warning("Mult_v2::multSub(), someKeys and someKeysIndices"); - } + if ((obj == -1) || (obj == 1024)) + continue; - for (i = 0; i < 4; i++) { - _multData->field_17F[index][i] = 0; - for (j = 0; j < _multData->someKeysCount[i]; j++) { - if (_multData->animDirection == 1) { - if (_multData->someKeys[i][j].frame >= _multData->animKeysStartFrames[index]) { - _multData->field_17F[index][i] = j; - break; - } - } else { - if (_multData->someKeys[i][j].frame >= _multData->animKeysStopFrames[index]) { - _multData->field_17F[index][i] = j; - break; - } - } - } + Mult_AnimData &animData = *(_objects[obj].pAnimData); + animData.animType = animData.animTypeBak; } - } -} -void Mult_v2::playMult(int16 startFrame, int16 endFrame, char checkEscape, - char handleMouse) { - char stopNoClear; - char stop; - Mult_Object *multObj; - Mult_AnimData *animData; - - if (_multData == 0) return; - - stopNoClear = 0; - _frame = startFrame; - if (endFrame == -1) - endFrame = 32767; - - if (_frame == -1) { - _doPalSubst = 0; - _palFadingRed = 0; - _palFadingGreen = 0; - _palFadingBlue = 0; - - _oldPalette = _vm->_global->_pPaletteDesc->vgaPal; - - if (_vm->_anim->_animSurf == 0) { - _vm->_util->setFrameRate(_multData->frameRate); - _vm->_anim->_areaTop = 0; - _vm->_anim->_areaLeft = 0; - _vm->_anim->_areaWidth = _vm->_video->_surfWidth; - _vm->_anim->_areaHeight = _vm->_video->_surfHeight; - _objCount = 4; - - if (_objects) - delete[] _objects; - if (_orderArray) - delete[] _orderArray; - if (_renderData2) - delete[] _renderData2; - - _objects = new Mult_Object[_objCount]; - memset(_objects, 0, _objCount * sizeof(Mult_Object)); - - _orderArray = new int8[_objCount]; - memset(_orderArray, 0, _objCount * sizeof(int8)); - _renderData2 = new Mult_Object*[_objCount]; - memset(_renderData2, 0, _objCount * sizeof(Mult_Object*)); - - _animArrayX = new int32[_objCount]; - _animArrayY = new int32[_objCount]; - - _animArrayData = new Mult_AnimData[_objCount]; - memset(_animArrayData, 0, _objCount * sizeof(Mult_AnimData)); - - for (_counter = 0; _counter < _objCount; _counter++) { - multObj = &_objects[_counter]; - - multObj->pPosX = (int32 *)&_animArrayX[_counter]; - multObj->pPosY = (int32 *)&_animArrayY[_counter]; - - multObj->pAnimData = &_animArrayData[_counter]; - - animData = multObj->pAnimData; - animData->isStatic = 1; - - multObj->tick = 0; - multObj->lastLeft = -1; - multObj->lastTop = -1; - multObj->lastRight = -1; - multObj->lastBottom = -1; - } - - _vm->_draw->adjustCoords(0, &_vm->_anim->_areaWidth, &_vm->_anim->_areaHeight); - _vm->_draw->initBigSprite(22, _vm->_anim->_areaWidth, _vm->_anim->_areaHeight, 0); - _vm->_anim->_animSurf = _vm->_draw->_spritesArray[22]; - - _vm->_draw->adjustCoords(1, &_vm->_anim->_areaWidth, &_vm->_anim->_areaHeight); - _vm->_draw->_sourceSurface = 21; - _vm->_draw->_destSurface = 22; - _vm->_draw->_destSpriteX = 0; - _vm->_draw->_destSpriteY = 0; - _vm->_draw->_spriteLeft = 0; - _vm->_draw->_spriteTop = 0; - _vm->_draw->_spriteRight = _vm->_video->_surfWidth; - _vm->_draw->_spriteBottom = _vm->_video->_surfHeight; - _vm->_draw->_transparency = 0; - _vm->_draw->spriteOperation(0); - _animDataAllocated = 1; - - for (_counter = 0; _counter < _objCount; _counter++) { - _multData->palAnimIndices[_counter] = _counter; - } - - _animDataAllocated = 1; - } else - _animDataAllocated = 0; - _frame = 0; } - do { - stop = 1; + startFrame = _multData->animKeysStartFrames[index]; + stopFrame = _multData->animKeysStopFrames[index]; - if (VAR(58) == 0) { - stop = drawStatics(stop); - stop = drawAnims(stop); - } + if (_multData->animDirection == 1) { + stopFrame = 32000; + for (int i = 0; i < _multData->textKeysCount; i++) { + int16 textFrame = _multData->textKeys[i].frame; - animate(); - if (handleMouse) { - _vm->_draw->animateCursor(-1); - } else { - _vm->_draw->blitInvalidated(); + if ((textFrame > startFrame) && (textFrame < stopFrame)) + stopFrame = textFrame; } + } else { + stopFrame = 0; + for (int i = 0; i < _multData->textKeysCount; i++) { + int16 textFrame = _multData->textKeys[i].frame; - if (VAR(58) == 0) { - drawText(&stop, &stopNoClear); + if ((textFrame < startFrame) && (textFrame > stopFrame)) + stopFrame = textFrame; } + } - stop = prepPalAnim(stop); - doPalAnim(); + if (_objects) { + for (int i = 0; i < 4; i++) { + int obj = _multData->animObjs[index][i]; - stop = doFadeAnim(stop); - stop = doSoundAnim(stop, _frame); + if ((obj != -1) && (obj != 1024)) + _objects[obj].pAnimData->animTypeBak = + _objects[obj].pAnimData->animType; + } + } - if (_frame >= endFrame) - stopNoClear = 1; + for (int i = 0; i < 4; i++) { + _multData->animKeysIndices[index][i] = 0; - if (_vm->_snd->_playingSound) - stop = 0; + for (int j = 0; j < _multData->animKeysCount[i]; j++) + if (_multData->animKeys[i][j].frame == startFrame) + _multData->animKeysIndices[index][i] = j; + } - _vm->_util->processInput(); - if (checkEscape && _vm->_util->checkKey() == 0x11b) // Esc - stop = 1; + if (_multData->animDirection == -1) { + for (int i = 0; i < _multData->imdKeysCount[i]; i++) { + if (_multData->imdKeys[index][i].frame > startFrame) + break; - _frame++; - _vm->_util->waitEndFrame(); - } while (stop == 0 && stopNoClear == 0 && !_vm->_quitRequested); + _multData->imdIndices[index] = i - 1; + } + } - if (stopNoClear == 0) { - if (_animDataAllocated) { - delete[] _objects; - _objects = 0; + firstFrame = (_multData->animDirection == 1) ? startFrame : stopFrame; + for (int i = 0; i < 4; i++) { + _multData->imdKeysIndices[index][i] = 0; + for (int j = 0; j < _multData->imdKeysCount[i]; j++) + if (_multData->imdKeys[i][j].frame >= firstFrame) + _multData->imdKeysIndices[index][i] = j; + } - delete[] _renderData2; - _renderData2 = 0; + _multData->animKeysStartFrames[index] = startFrame; + _multData->animKeysStopFrames[index] = stopFrame; +} - delete[] _animArrayX; - _animArrayX = 0; +void Mult_v2::playMultInit() { + _doPalSubst = false; + _palFadingRed = 0; + _palFadingGreen = 0; + _palFadingBlue = 0; - delete[] _animArrayY; - _animArrayY = 0; + _oldPalette = _vm->_global->_pPaletteDesc->vgaPal; - delete[] _animArrayData; - _animArrayData = 0; + if (!_animSurf) { + int16 width, height; - delete[] _orderArray; - _orderArray = 0; + _vm->_util->setFrameRate(_multData->frameRate); + _animTop = 0; + _animLeft = 0; + _animWidth = _vm->_video->_surfWidth; + _animHeight = _vm->_video->_surfHeight; + _objCount = 4; - _vm->_video->freeSurfDesc(_vm->_anim->_animSurf); - _vm->_anim->_animSurf = 0; - _vm->_draw->_spritesArray[22] = 0; + delete[] _objects; + delete[] _orderArray; + delete[] _renderObjs; + delete[] _animArrayX; + delete[] _animArrayY; + delete[] _animArrayData; - _animDataAllocated = 0; + _objects = new Mult_Object[_objCount]; + _orderArray = new int8[_objCount]; + _renderObjs = new Mult_Object*[_objCount]; + _animArrayX = new int32[_objCount]; + _animArrayY = new int32[_objCount]; + _animArrayData = new Mult_AnimData[_objCount]; + + memset(_objects, 0, _objCount * sizeof(Mult_Object)); + memset(_orderArray, 0, _objCount * sizeof(int8)); + memset(_renderObjs, 0, _objCount * sizeof(Mult_Object *)); + memset(_animArrayX, 0, _objCount * sizeof(int32)); + memset(_animArrayY, 0, _objCount * sizeof(int32)); + memset(_animArrayData, 0, _objCount * sizeof(Mult_AnimData)); + + for (_counter = 0; _counter < _objCount; _counter++) { + Mult_Object &multObj = _objects[_counter]; + Mult_AnimData &animData = _animArrayData[_counter]; + + multObj.pPosX = (int32 *) &_animArrayX[_counter]; + multObj.pPosY = (int32 *) &_animArrayY[_counter]; + multObj.pAnimData = &animData; + + animData.isStatic = 1; + + multObj.lastLeft = -1; + multObj.lastTop = -1; + multObj.lastRight = -1; + multObj.lastBottom = -1; } - if (_vm->_snd->_playingSound != 0) - _vm->_snd->stopSound(10); + width = _animWidth; + height = _animHeight; + _vm->_draw->adjustCoords(0, &width, &height); + _vm->_draw->initSpriteSurf(22, width, height, 0); + _animSurf = _vm->_draw->_spritesArray[22]; + + _vm->_video->drawSprite(_vm->_draw->_spritesArray[21], + _vm->_draw->_spritesArray[22], 0, 0, + _vm->_video->_surfWidth, _vm->_video->_surfHeight, 0, 0, 0); + + for (_counter = 0; _counter < _objCount; _counter++) + _multData->palAnimIndices[_counter] = _counter; - WRITE_VAR(57, (uint32)-1); + _animDataAllocated = true; } else - WRITE_VAR(57, _frame - 1 - _multData->frameStart); + _animDataAllocated = false; + + _frame = 0; } -char Mult_v2::drawStatics(char stop) { - int i; +void Mult_v2::drawStatics(bool &stop) { + int staticIndex; if (_multData->staticKeys[_multData->staticKeysCount - 1].frame > _frame) - stop = 0; + stop = false; for (_counter = 0; _counter < _multData->staticKeysCount; _counter++) { - if (_multData->staticKeys[_counter].frame != _frame - || _multData->staticKeys[_counter].layer == -1) + if ((_multData->staticKeys[_counter].frame != _frame) + || (_multData->staticKeys[_counter].layer == -1)) continue; - // loc_4FA8 if (_multData->staticKeys[_counter].layer >= 0) { + int i = 0; _vm->_scenery->_curStatic = 0; - _vm->_scenery->_curStaticLayer = _multData->staticKeys[_counter].layer; + _vm->_scenery->_curStaticLayer = + _multData->staticKeys[_counter].layer; - i = 0; - while (_vm->_scenery->_statics[_multData->staticIndices[i]].layersCount <= _vm->_scenery->_curStaticLayer) { + staticIndex = _multData->staticIndices[i]; + while(_vm->_scenery->getStaticLayersCount(staticIndex) <= + _vm->_scenery->_curStaticLayer) { _vm->_scenery->_curStaticLayer -= - _vm->_scenery->_statics[_multData->staticIndices[i]].layersCount; - i++; + _vm->_scenery->getStaticLayersCount(staticIndex); + + staticIndex = _multData->staticIndices[++i]; _vm->_scenery->_curStatic++; } - _vm->_scenery->_curStatic = _multData->staticIndices[_vm->_scenery->_curStatic]; - _vm->_scenery->renderStatic(_vm->_scenery->_curStatic, _vm->_scenery->_curStaticLayer); + _vm->_scenery->_curStatic = + _multData->staticIndices[_vm->_scenery->_curStatic]; + _vm->_scenery->renderStatic(_vm->_scenery->_curStatic, + _vm->_scenery->_curStaticLayer); } else { + int layer = -_multData->staticKeys[_counter].layer - 2; + _vm->_draw->_spriteLeft = - READ_LE_UINT16(_multData->execPtr + ((-_multData->staticKeys[_counter].layer - 2) * 2)); + READ_LE_UINT16(_multData->execPtr + layer * 2); _vm->_draw->_destSpriteX = 0; _vm->_draw->_destSpriteY = 0; _vm->_draw->_destSurface = 21; _vm->_draw->_transparency = 0; - _vm->_draw->spriteOperation(5); + _vm->_draw->spriteOperation(DRAW_LOADSPRITE); _vm->_scenery->_curStatic = -1; } - _vm->_draw->_sourceSurface = 21; - _vm->_draw->_destSurface = 22; - _vm->_draw->_destSpriteX = 0; - _vm->_draw->_destSpriteY = 0; - _vm->_draw->_spriteLeft = 0; - _vm->_draw->_spriteTop = 0; - _vm->_draw->_spriteRight = _vm->_video->_surfWidth; - _vm->_draw->_spriteBottom = _vm->_video->_surfHeight; - _vm->_draw->_transparency = 0; - _vm->_draw->spriteOperation(0); + + _vm->_video->drawSprite(_vm->_draw->_spritesArray[21], + _vm->_draw->_spritesArray[22], 0, 0, + _vm->_video->_surfWidth, _vm->_video->_surfHeight, 0, 0, 0); } - return stop; } -char Mult_v2::drawAnims(char stop) { // loc_50D5 - Mult_AnimKey *key; - Mult_Object *animObj; - int16 i; +void Mult_v2::drawAnims(bool &stop) { // loc_50D5 int16 count; + int animIndex; - for (i = 0; i < 4; i++) { - if (_multData->animKeys[i][_multData->animKeysCount[i] - 1].frame > _frame) - stop = 0; + for (int i = 0; i < 4; i++) { + int16 animKeysCount = _multData->animKeysCount[i]; + if (_multData->animKeys[i][animKeysCount - 1].frame > _frame) + stop = false; } for (_index = 0; _index < 4; _index++) { - for (_counter = 0; _counter < _multData->animKeysCount[_index]; _counter++) { - key = &_multData->animKeys[_index][_counter]; - animObj = &_objects[_multData->field_124[0][_index]]; - if (key->frame != _frame) + int16 animKeysCount = _multData->animKeysCount[_index]; + for (_counter = 0; _counter < animKeysCount; _counter++) { + Mult_AnimKey &key = _multData->animKeys[_index][_counter]; + Mult_Object &animObj = _objects[_multData->animObjs[0][_index]]; + Mult_AnimData &animData = *(animObj.pAnimData); + + if (key.frame != _frame) continue; - if (key->layer != -1) { - (*animObj->pPosX) = key->posX; - (*animObj->pPosY) = key->posY; - - animObj->pAnimData->frame = 0; - animObj->pAnimData->order = key->order; - animObj->pAnimData->animType = 1; - - animObj->pAnimData->isPaused = 0; - animObj->pAnimData->isStatic = 0; - animObj->pAnimData->maxTick = 0; - animObj->tick = 0; - animObj->pAnimData->layer = key->layer; - - count = _vm->_scenery->_animations[_multData->animIndices[0]].layersCount; - i = 0; - while (animObj->pAnimData->layer >= count) { - animObj->pAnimData->layer -= count; - i++; - - count = _vm->_scenery->_animations[_multData->animIndices[i]].layersCount; + if (key.layer != -1) { + *(animObj.pPosX) = key.posX; + *(animObj.pPosY) = key.posY; + + animData.frame = 0; + animData.order = key.order; + animData.animType = 1; + + animData.isPaused = 0; + animData.isStatic = 0; + animData.maxTick = 0; + animObj.tick = 0; + animData.layer = key.layer; + + int i = 0; + animIndex = _multData->animIndices[i]; + count = _vm->_scenery->getAnimLayersCount(animIndex); + while (animData.layer >= count) { + animData.layer -= count; + animIndex = _multData->animIndices[++i]; + + count = _vm->_scenery->getAnimLayersCount(animIndex); } - animObj->pAnimData->animation = _multData->animIndices[i]; - } else { - animObj->pAnimData->isStatic = 1; - } + animData.animation = animIndex; + + } else + animData.isStatic = 1; } } - - return stop; } -void Mult_v2::drawText(char *pStop, char *pStopNoClear) { - char *savedIP; - - int16 cmd; - for (_index = 0; _index < _multData->textKeysCount; _index++) { - if (_multData->textKeys[_index].frame != _frame) - continue; +void Mult_v2::newCycleAnim(Mult_Object &animObj) { + Mult_AnimData &animData = *(animObj.pAnimData); + int nAnim = animData.animation; + int nLayer = animData.layer; + Scenery::AnimLayer *animLayer = _vm->_scenery->getAnimLayer(nAnim, nLayer); - cmd = _multData->textKeys[_index].cmd; - if (cmd == 0) { - *pStop = 0; - } else if (cmd == 1) { - *pStopNoClear = 1; - _multData->frameStart = 0; - } else if (cmd == 3) { - *pStop = 0; - savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = (char *)(&_multData->textKeys[_index].index); - _vm->_global->_inter_execPtr = savedIP; - } + if (animData.animType == 4) { + animData.frame = 0; + animData.isPaused = 1; + return; } -} -char Mult_v2::prepPalAnim(char stop) { - _palKeyIndex = -1; - do { - _palKeyIndex++; - if (_palKeyIndex >= _multData->palKeysCount) - return stop; - } while (_multData->palKeys[_palKeyIndex].frame != _frame); - - if (_multData->palKeys[_palKeyIndex].cmd == -1) { - stop = 0; - _doPalSubst = 0; - _vm->_global->_pPaletteDesc->vgaPal = _oldPalette; - _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); - } else { - stop = 0; - _doPalSubst = 1; - _palAnimKey = _palKeyIndex; + if (animData.animType != 8) + animData.frame++; - _multData->palAnimIndices[0] = 0; - _multData->palAnimIndices[1] = 0; - _multData->palAnimIndices[2] = 0; - _multData->palAnimIndices[3] = 0; + if (animData.frame < animLayer->framesCount) { + animData.newCycle = 0; + return; + } - memcpy((char *)_palAnimPalette, (char *)_vm->_global->_pPaletteDesc->vgaPal, 768); - _vm->_global->_pPaletteDesc->vgaPal = _palAnimPalette; + switch (animData.animType) { + case 0: + animData.frame = 0; + break; + + case 1: + animData.frame = 0; + *(animObj.pPosX) += animLayer->animDeltaX; + *(animObj.pPosY) += animLayer->animDeltaY; + break; + + case 2: + animData.frame = 0; + animData.animation = animData.newAnimation; + animData.layer = animData.newLayer; + break; + + case 3: + animData.animType = 4; + animData.frame = 0; + break; + + case 5: + animData.isStatic = 1; + animData.frame = 0; + break; + + case 6: + case 7: + animData.frame--; + animData.isPaused = 1; + break; } - return stop; + animData.newCycle = 1; } -void Mult_v2::doPalAnim(void) { - int16 off; - int16 off2; - Video::Color *palPtr; - Mult_PalKey *palKey; - - if (_doPalSubst == 0) +void Mult_v2::animate() { + int8 minOrder = 100; + int8 maxOrder = 0; + int8 *orderArray; + int orderArrayPos = 0; + int8 animIndices[150]; + int numAnims = 0; + + if (!_objects) return; - for (_index = 0; _index < 4; _index++) { - palKey = &_multData->palKeys[_palAnimKey]; - - if ((_frame % palKey->rates[_index]) != 0) - continue; - - _palAnimRed[_index] = - _vm->_global->_pPaletteDesc->vgaPal[palKey->subst[0][_index] - 1].red; - _palAnimGreen[_index] = - _vm->_global->_pPaletteDesc->vgaPal[palKey->subst[0][_index] - 1].green; - _palAnimBlue[_index] = - _vm->_global->_pPaletteDesc->vgaPal[palKey->subst[0][_index] - 1].blue; - - while (1) { - off = palKey->subst[(_multData->palAnimIndices[_index] + 1) % 16][_index]; - if (off == 0) { - off = palKey->subst[_multData->palAnimIndices[_index]][_index] - 1; - - _vm->_global->_pPaletteDesc->vgaPal[off].red = _palAnimRed[_index]; - _vm->_global->_pPaletteDesc->vgaPal[off].green = _palAnimGreen[_index]; - _vm->_global->_pPaletteDesc->vgaPal[off].blue = _palAnimBlue[_index]; - } else { - off = palKey->subst[(_multData->palAnimIndices[_index] + 1) % 16][_index] - 1; - off2 = palKey->subst[_multData->palAnimIndices[_index]][_index] - 1; - - _vm->_global->_pPaletteDesc->vgaPal[off2].red = - _vm->_global->_pPaletteDesc->vgaPal[off].red; - _vm->_global->_pPaletteDesc->vgaPal[off2].green = - _vm->_global->_pPaletteDesc->vgaPal[off].green; - _vm->_global->_pPaletteDesc->vgaPal[off2].blue = - _vm->_global->_pPaletteDesc->vgaPal[off].blue; - } - - _multData->palAnimIndices[_index] = (_multData->palAnimIndices[_index] + 1) % 16; - - off = palKey->subst[_multData->palAnimIndices[_index]][_index]; - - if (off == 0) { - _multData->palAnimIndices[_index] = 0; - off = palKey->subst[0][_index] - 1; + if (_objCount > 0) { + if (!_orderArray) + return; + orderArray = _orderArray; + } else + orderArray = 0; - _palAnimRed[_index] = _vm->_global->_pPaletteDesc->vgaPal[off].red; - _palAnimGreen[_index] = _vm->_global->_pPaletteDesc->vgaPal[off].green; - _palAnimBlue[_index] = _vm->_global->_pPaletteDesc->vgaPal[off].blue; + advanceAllObjects(); + + // Find relevant objects + for (int i = 0; i < _objCount; i++) { + Mult_Object &animObj = _objects[i]; + Mult_AnimData &animData = *(animObj.pAnimData); + + animData.intersected = 200; + if (animData.isStatic != 2) { + if ((animData.isStatic == 0) || (animObj.lastLeft != -1)) { + animIndices[numAnims] = i; + _renderObjs[numAnims] = &animObj; + numAnims++; } - if (_multData->palAnimIndices[_index] == 0) - break; } } - if (_vm->_global->_colorCount == 256) { - _vm->_video->waitRetrace(_vm->_global->_videoMode); + // Find dirty areas + for (int i = 0; i < numAnims; i++) { + Mult_Object &animObj = *_renderObjs[i]; + Mult_AnimData &animData = *(animObj.pAnimData); - palPtr = _vm->_global->_pPaletteDesc->vgaPal; - for (_counter = 0; _counter < 16; _counter++) { - _vm->_video->setPalElem(_counter, palPtr->red, palPtr->green, palPtr->blue, 0, 0x13); - palPtr++; - } - - palPtr = _vm->_global->_pPaletteDesc->vgaPal; - for (_counter = 0; _counter < 16; _counter++) { - _vm->_global->_redPalette[_counter] = palPtr->red; - _vm->_global->_greenPalette[_counter] = palPtr->green; - _vm->_global->_bluePalette[_counter] = palPtr->blue; - palPtr++; - } - } else { - _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); - } -} - -char Mult_v2::doFadeAnim(char stop) { - Mult_PalFadeKey *fadeKey; - - for (_index = 0; _index < _multData->palFadeKeysCount; _index++) { - fadeKey = &_multData->palFadeKeys[_index]; - - if (fadeKey->frame != _frame) + animObj.needRedraw = 0; + animObj.newTop = 1000; + animObj.newLeft = 1000; + animObj.newBottom = 0; + animObj.newRight = 0; + + if (animData.isStatic == 2) continue; - stop = 0; - if ((fadeKey->flag & 1) == 0) { - if (fadeKey->fade == 0) { - _vm->_global->_pPaletteDesc->vgaPal = _multData->fadePal[fadeKey->palIndex]; - _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); + if (!animData.isStatic && !animData.isPaused && + (animData.maxTick == animObj.tick)) { + + animObj.needRedraw = 1; + _vm->_scenery->updateAnim(animData.layer, animData.frame, + animData.animation, 8, *animObj.pPosX, *animObj.pPosY, 0); + if (animObj.lastLeft == -1) { + animObj.newLeft = _vm->_scenery->_toRedrawLeft; + animObj.newTop = _vm->_scenery->_toRedrawTop; + animObj.newRight = _vm->_scenery->_toRedrawRight; + animObj.newBottom = _vm->_scenery->_toRedrawBottom; } else { - _vm->_global->_pPaletteDesc->vgaPal = _multData->fadePal[fadeKey->palIndex]; - _vm->_palanim->fade(_vm->_global->_pPaletteDesc, fadeKey->fade, 0); + animObj.newLeft = + MIN(animObj.lastLeft, _vm->_scenery->_toRedrawLeft); + animObj.newTop = + MIN(animObj.lastTop, _vm->_scenery->_toRedrawTop); + animObj.newRight = + MAX(animObj.lastRight, _vm->_scenery->_toRedrawRight); + animObj.newBottom = + MAX(animObj.lastBottom, _vm->_scenery->_toRedrawBottom); + + if ((_vm->_game->_totFileData[0x29] > 50) && + (animObj.newLeft == animObj.lastLeft) && + (animObj.newTop == animObj.lastTop) && + (animObj.newRight == animObj.lastRight) && + (animObj.newBottom == animObj.lastBottom) && + (animData.redrawLayer == animData.layer) && + (animData.redrawFrame == animData.frame) && + (animData.redrawAnimation == animData.animation)) { + animObj.needRedraw = 0; + } } - } else { - _vm->_global->_pPaletteDesc->vgaPal = _multData->fadePal[fadeKey->palIndex]; - _vm->_palanim->fade(_vm->_global->_pPaletteDesc, fadeKey->fade, -1); - _palFadingRed = (fadeKey->flag >> 1) & 1; - _palFadingGreen = (fadeKey->flag >> 2) & 1; - _palFadingBlue = (fadeKey->flag >> 3) & 1; - } - } + } else if (!animData.isStatic) { - if (_palFadingRed) { - _palFadingRed = !_vm->_palanim->fadeStep(1); - stop = 0; - } - if (_palFadingGreen) { - _palFadingGreen = !_vm->_palanim->fadeStep(2); - stop = 0; - } - if (_palFadingBlue) { - _palFadingBlue = !_vm->_palanim->fadeStep(3); - stop = 0; - } - return stop; -} + if (animObj.lastLeft == -1) { + animObj.needRedraw = 1; + _vm->_scenery->updateAnim(animData.layer, animData.frame, + animData.animation, 8, *animObj.pPosX, *animObj.pPosY, 0); -char Mult_v2::doSoundAnim(char stop, int16 frame) { - Mult_SndKey *sndKey; - for (_index = 0; _index < _multData->sndKeysCount; _index++) { - sndKey = &_multData->sndKeys[_index]; - if (sndKey->frame != frame) - continue; - - if (sndKey->cmd != -1) { - if ((sndKey->cmd == 1) || (sndKey->cmd == 4)) { - _vm->_snd->stopSound(0); - if (_vm->_game->_soundSamples[sndKey->soundIndex] == 0) - continue; - playSound(_vm->_game->_soundSamples[sndKey->soundIndex], sndKey->repCount, - sndKey->freq, sndKey->fadeLength); + animObj.newLeft = _vm->_scenery->_toRedrawLeft; + animObj.newTop = _vm->_scenery->_toRedrawTop; + animObj.newRight = _vm->_scenery->_toRedrawRight; + animObj.newBottom = _vm->_scenery->_toRedrawBottom; + } else { + animObj.newLeft = animObj.lastLeft; + animObj.newTop = animObj.lastTop; + animObj.newRight = animObj.lastRight; + animObj.newBottom = animObj.lastBottom; } - } else { - if (_vm->_snd->_playingSound) - _vm->_snd->stopSound(sndKey->fadeLength); - } - } - return stop; -} -// "deplaceheros" -void Mult_v2::sub_62DD(int16 index) { - Mult_Object *animObj; - Mult_AnimKey *animKey; - Mult_SomeKey *someKey1, *someKey2; - int16 frame; - int16 layer; - int16 layers; - int16 curAnim; - int i, j; - - frame = _multData->animKeysFrames[index]; - if (frame == -1) - return; - - for (i = 0; i < 4; i++) { - if (_multData->field_124[index][i] != -1) { - for (j = _multData->animKeysIndices[index][i]; j < _multData->animKeysCount[i]; j++) { - if ((i >= 4) || (j >= _multData->animKeysCount[i])) - continue; - animKey = &_multData->animKeys[i][j]; - if (animKey->frame == frame) { - animObj = &_objects[_multData->field_124[index][i]]; - if (animKey->layer > -1) { - _multData->animKeysIndices[index][i] = j; - (*animObj->pPosX) = animKey->posX; - (*animObj->pPosY) = animKey->posY; - animObj->pAnimData->frame = 0; - animObj->pAnimData->animType = 1; - animObj->pAnimData->isStatic = 0; - animObj->pAnimData->isPaused = 0; - animObj->pAnimData->maxTick = 0; - animObj->pAnimData->animation = 0; - animObj->tick = 0; - curAnim = _multData->animIndices[0]; - layer = animKey->layer; - layers = _vm->_scenery->_animations[curAnim].layersCount; - while (layer >= layers) { - layer -= layers; - animObj->pAnimData->animation++; - curAnim = _multData->animIndices[animObj->pAnimData->animation]; - layers = _vm->_scenery->_animations[curAnim].layersCount; - } - animObj->pAnimData->layer = layer; - animObj->pAnimData->animation = - _multData->animIndices[animObj->pAnimData->animation]; - break; - } else - animObj->pAnimData->isStatic = 1; - } else if (animKey->frame > frame) - break; - } + } else if (animObj.lastLeft != -1) { + animObj.needRedraw = 1; + animObj.newLeft = animObj.lastLeft; + animObj.newTop = animObj.lastTop; + animObj.newRight = animObj.lastRight; + animObj.newBottom = animObj.lastBottom; } - if (_multData->field_124[index][i] != -1) { - for (j = _multData->field_17F[index][i]; j < _multData->someKeysCount[i]; j++) { - someKey1 = &_multData->someKeys[i][j]; - someKey2 = &_multData->someKeys[i][j-1]; - if (someKey1->frame == frame) { - if (someKey1->field_2 != -1) { - _multData->someKeysIndices[0] = -1; - _multData->someKeysIndices[1] = -1; - _multData->someKeysIndices[2] = -1; - _multData->someKeysIndices[3] = -1; - if ((_multData->animDirection == 1) || (someKey2->field_2 == 1)) - _multData->someKeysIndices[i] = j; - else if (_multData->animKeysStopFrames[index] == frame) - _multData->someKeysIndices[i] = -1; - else - _multData->someKeysIndices[i] = j - 1; - } else - _multData->someKeysIndices[i] = -1; - } else if (someKey1->frame > frame) - break; - } - } - if (_multData->someKeysIndices[i] != -1) { -/* - int arg3 = frame - _multData->someKeys[i][_multData->someKeysIndices[i]].field_0; - int arg2 = _multData->animDirection; - if ((arg2 != 1) && (--arg3 > 0)) - arg3 = 0; - int arg1 = _multData->someKeys[i][_multData->someKeysIndices[i]]; - // somepointer09 is 14 bytes wide (surely a struct) - int arg0 = _multData->somepointer09[-_multData->someKeys[i][_multData->someKeysIndices[i]].field_2 - 2]; -*/ - warning("GOB2 Stub! sub_1CBF8(arg0, arg1, arg2, arg3);"); + animData.redrawLayer = animData.layer; + animData.redrawFrame = animData.frame; + animData.redrawAnimation = animData.animation; + if (animObj.needRedraw || !animData.isStatic) { + minOrder = MIN(minOrder, animData.order); + maxOrder = MAX(maxOrder, animData.order); } } - - doSoundAnim(0, frame); - WRITE_VAR(22, frame); - - if (_multData->animKeysStopFrames[index] == frame) { - _multData->someKeysIndices[0] = -1; - _multData->someKeysIndices[1] = -1; - _multData->someKeysIndices[2] = -1; - _multData->someKeysIndices[3] = -1; - frame = -1; - for (i = 0; i < 4; i++) - if ((_multData->field_124[index][i] != -1) && (_multData->field_124[index][i] != 1024)) - _objects[_multData->field_124[index][i]].pAnimData->animType = - _objects[_multData->field_124[index][i]].pAnimData->field_17; - } else if (_multData->animDirection == 1) - frame++; - else - frame--; - // loc_6A06 - _multData->animKeysFrames[index] = frame; - WRITE_VAR(18 + index, frame); -} + // Restore dirty areas + for (int i = 0; i < numAnims; i++) { + Mult_Object &animObj = *_renderObjs[i]; -// "avancerperso" -void Mult_v2::sub_6A35(void) { - int i; - int j; - - for (i = 0; i < 8; i++) - if (_multDatas[i] != 0) { - _multData = _multDatas[i]; - for (j = 0; j < 4; j++) - sub_62DD(j); - } -} + if (!animObj.needRedraw || (animObj.lastLeft == -1)) + continue; -void Mult_v2::animate(void) { - Mult_Object *animObj1, *animObj2; - Mult_AnimData *animData1, *animData2; - int i; - int j; - int8 minOrder = 100; - int8 maxOrder = 0; - int8 *orderArray; - int orderArrayPos = 0; - int8 animIndices[150]; - int numAnims = 0; // di - - if (_objects == 0) - return; + animObj.lastLeft = -1; - if (_objCount == 0) - orderArray = 0; - else { - if (_orderArray == 0) - return; - orderArray = _orderArray; - } + int maxleft = MAX(animObj.newLeft, _animLeft); + int maxtop = MAX(animObj.newTop, _animTop); + int right = animObj.newRight - maxleft + 1; + int bottom = animObj.newBottom - maxtop + 1; - sub_6A35(); - - for (i = 0; i < _objCount; i++) { - animData1 = _objects[i].pAnimData; - animData1->intersected = 200; - if ((animData1->isStatic != 2) && - ((animData1->isStatic == 0) || (_objects[i].lastLeft != -1))) { - animIndices[numAnims] = i; - _renderData2[numAnims] = &_objects[i]; - numAnims++; - } - } - - for (i = 0; i < numAnims; i++) { - animObj1 = _renderData2[i]; + if ((right <= 0) || (bottom <= 0)) + continue; - animObj1->someFlag = 0; - animObj1->somethingTop = 1000; - animObj1->somethingLeft = 1000; - animObj1->somethingBottom = 0; - animObj1->somethingRight = 0; - - animData1 = animObj1->pAnimData; - - if (animData1->isStatic != 2) { - if ((animData1->isStatic == 0) && (animData1->isPaused == 0) - && (animData1->maxTick == animObj1->tick)) { - animObj1->someFlag = 1; - _vm->_scenery->updateAnim(animData1->layer, animData1->frame, - animData1->animation, 8, *animObj1->pPosX, *animObj1->pPosY, 0); - if (animObj1->lastLeft == -1) { - animObj1->somethingLeft = _vm->_scenery->_toRedrawLeft; - animObj1->somethingTop = _vm->_scenery->_toRedrawTop; - animObj1->somethingRight = _vm->_scenery->_toRedrawRight; - animObj1->somethingBottom = _vm->_scenery->_toRedrawBottom; - } else { - animObj1->somethingLeft = MIN(animObj1->lastLeft, _vm->_scenery->_toRedrawLeft); - animObj1->somethingTop = MIN(animObj1->lastTop, _vm->_scenery->_toRedrawTop); - animObj1->somethingRight = MAX(animObj1->lastRight, _vm->_scenery->_toRedrawRight); - animObj1->somethingBottom = MAX(animObj1->lastBottom, _vm->_scenery->_toRedrawBottom); - if ((_vm->_game->_totFileData[0x29] > 50) && - (animObj1->somethingLeft == animObj1->lastLeft) && - (animObj1->somethingTop == animObj1->lastTop) && - (animObj1->somethingRight == animObj1->lastRight) && - (animObj1->somethingBottom == animObj1->lastBottom) && - (animData1->somethingLayer == animData1->layer) && - (animData1->somethingFrame == animData1->frame) && - (animData1->somethingAnimation == animData1->animation)) { - animObj1->someFlag = 0; - } - } - } else if (animData1->isStatic == 0) { - if (animObj1->lastLeft == -1) { - animObj1->someFlag = 1; - _vm->_scenery->updateAnim(animData1->layer, animData1->frame, - animData1->animation, 8, *animObj1->pPosX, *animObj1->pPosY, 0); - animObj1->somethingLeft = _vm->_scenery->_toRedrawLeft; - animObj1->somethingTop = _vm->_scenery->_toRedrawTop; - animObj1->somethingRight = _vm->_scenery->_toRedrawRight; - animObj1->somethingBottom = _vm->_scenery->_toRedrawBottom; - } else { - animObj1->somethingLeft = animObj1->lastLeft; - animObj1->somethingTop = animObj1->lastTop; - animObj1->somethingRight = animObj1->lastRight; - animObj1->somethingBottom = animObj1->lastBottom; - } - } else if (animObj1->lastLeft != -1) { - animObj1->someFlag = 1; - animObj1->somethingLeft = animObj1->lastLeft; - animObj1->somethingTop = animObj1->lastTop; - animObj1->somethingRight = animObj1->lastRight; - animObj1->somethingBottom = animObj1->lastBottom; - } - animData1->somethingLayer = animData1->layer; - animData1->somethingFrame = animData1->frame; - animData1->somethingAnimation = animData1->animation; - if ((animObj1->someFlag != 0) || (animData1->isStatic == 0)) { - minOrder = MIN(minOrder, animData1->order); - maxOrder = MAX(maxOrder, animData1->order); - } - } + _vm->_draw->_sourceSurface = 22; + _vm->_draw->_destSurface = 21; + _vm->_draw->_spriteLeft = maxleft - _animLeft; + _vm->_draw->_spriteTop = maxtop - _animTop; + _vm->_draw->_spriteRight = right; + _vm->_draw->_spriteBottom = bottom; + _vm->_draw->_destSpriteX = maxleft; + _vm->_draw->_destSpriteY = maxtop; + _vm->_draw->_transparency = 0; + _vm->_draw->spriteOperation(DRAW_DRAWLETTER); } - for (i = 0; i < numAnims; i++) { - if ((_renderData2[i]->someFlag != 0) && (_renderData2[i]->lastLeft != -1)) { - int maxleft = MAX(_renderData2[i]->somethingLeft, _vm->_anim->_areaLeft); - int maxtop = MAX(_renderData2[i]->somethingTop, _vm->_anim->_areaTop); - - _vm->_draw->_sourceSurface = 22; - _vm->_draw->_destSurface = 21; - _vm->_draw->_spriteLeft = maxleft - _vm->_anim->_areaLeft; - _vm->_draw->_spriteTop = maxtop - _vm->_anim->_areaTop; - _vm->_draw->_spriteRight = _renderData2[i]->somethingRight - maxleft + 1; - _vm->_draw->_spriteBottom = _renderData2[i]->somethingBottom - maxtop + 1; - if ((_vm->_draw->_spriteRight > 0) && (_vm->_draw->_spriteBottom > 0)) { - _vm->_draw->_destSpriteX = maxleft; - _vm->_draw->_destSpriteY = maxtop; - _vm->_draw->_transparency = 0; - _vm->_draw->spriteOperation(10); - } - _renderData2[i]->lastLeft = -1; - } - } + // Figure out the correct drawing order + for (int i = minOrder; i <= maxOrder; i++) { + for (int j = 0; j < numAnims; j++) { + Mult_Object &animObj = *_renderObjs[j]; + Mult_AnimData &animData = *(animObj.pAnimData); - for (j = minOrder; j <= maxOrder; j++) { - for (i = 0; i < numAnims; i++) { - animData1 = _renderData2[i]->pAnimData; - if (((animData1->isStatic == 0) || (_renderData2[i]->someFlag != 0)) - && (animData1->order == j)) - orderArray[orderArrayPos++] = i; + if (animData.order == i) + if (animObj.needRedraw || !animData.isStatic) + orderArray[orderArrayPos++] = j; } } + // Put the goblins in correct drawing order as well if (_vm->_goblin->_gobsCount >= 0) { - for (i = 0; i < orderArrayPos; i++) { - animObj1 = _renderData2[orderArray[i]]; - for (j = i+1; j < orderArrayPos; j++) { - animObj2 = _renderData2[orderArray[j]]; - if ((animObj1->pAnimData->order == animObj2->pAnimData->order) && - ((animObj1->somethingBottom > animObj2->somethingBottom) || - ((animObj1->somethingBottom == animObj2->somethingBottom) && - (animObj1->pAnimData->isBusy == 1)))) + for (int i = 0; i < orderArrayPos; i++) { + Mult_Object &animObj1 = *_renderObjs[orderArray[i]]; + Mult_AnimData &animData1 = *(animObj1.pAnimData); + + for (int j = i+1; j < orderArrayPos; j++) { + Mult_Object &animObj2 = *_renderObjs[orderArray[j]]; + Mult_AnimData &animData2 = *(animObj2.pAnimData); + + if ((animData1.order == animData2.order) && + ((animObj1.newBottom > animObj2.newBottom) || + ((animObj1.newBottom == animObj2.newBottom) && + (animData1.isBusy == 1)))) SWAP(orderArray[i], orderArray[j]); } } } - for (i = 0; i < orderArrayPos; i++) { - animObj1 = _renderData2[orderArray[i]]; - animData1 = animObj1->pAnimData; - if ((animObj1->someFlag == 0) && (animData1->isStatic == 0)) { - for (j = 0; j < orderArrayPos; j++) { - animObj2 = _renderData2[orderArray[j]]; - if ((animObj2->someFlag != 0) && - (animObj1->somethingRight >= animObj2->somethingLeft) && - (animObj2->somethingRight >= animObj1->somethingLeft) && - (animObj1->somethingBottom >= animObj2->somethingTop) && - (animObj2->somethingBottom >= animObj1->somethingTop)) + // Update view + for (int i = 0; i < orderArrayPos; i++) { + Mult_Object &animObj1 = *_renderObjs[orderArray[i]]; + Mult_AnimData &animData1 = *(animObj1.pAnimData); + + if (!animObj1.needRedraw && !animData1.isStatic) { + for (int j = 0; j < orderArrayPos; j++) { + Mult_Object &animObj2 = *_renderObjs[orderArray[j]]; + + if (!animObj2.needRedraw) + continue; + + if ((animObj1.newRight >= animObj2.newLeft) && + (animObj2.newRight >= animObj1.newLeft) && + (animObj1.newBottom >= animObj2.newTop) && + (animObj2.newBottom >= animObj1.newTop)) { - _vm->_scenery->_toRedrawLeft = animObj2->somethingLeft; - _vm->_scenery->_toRedrawRight = animObj2->somethingRight; - _vm->_scenery->_toRedrawTop = animObj2->somethingTop; - _vm->_scenery->_toRedrawBottom = animObj2->somethingBottom; - _vm->_scenery->updateAnim(animData1->layer, animData1->frame, - animData1->animation, 12, *animObj1->pPosX, *animObj1->pPosY, 1); - _vm->_scenery->updateStatic(animObj1->pAnimData->order + 1); + _vm->_scenery->_toRedrawLeft = animObj2.newLeft; + _vm->_scenery->_toRedrawRight = animObj2.newRight; + _vm->_scenery->_toRedrawTop = animObj2.newTop; + _vm->_scenery->_toRedrawBottom = animObj2.newBottom; + + _vm->_scenery->updateAnim(animData1.layer, animData1.frame, + animData1.animation, 12, *animObj1.pPosX, *animObj1.pPosY, 1); + _vm->_scenery->updateStatic(animData1.order + 1); } } - } else if (animData1->isStatic == 0) { - _vm->_scenery->updateAnim(animData1->layer, animData1->frame, - animData1->animation, 10, *animObj1->pPosX, *animObj1->pPosY, 1); + } else if (!animData1.isStatic) { + _vm->_scenery->updateAnim(animData1.layer, animData1.frame, + animData1.animation, 10, *animObj1.pPosX, *animObj1.pPosY, 1); + if (_vm->_scenery->_toRedrawLeft != -12345) { if (_vm->_global->_pressedKeys[0x36]) { - warning("GOB2 Stub! word_2F3BF & word_2F3C1; someValueToAddToY & someValueToAddToX, respectively"); - // draws a rectangle around the region to redraw, why? _vm->_video->drawLine(_vm->_draw->_frontSurface, _vm->_scenery->_toRedrawLeft, _vm->_scenery->_toRedrawTop, _vm->_scenery->_toRedrawRight, _vm->_scenery->_toRedrawTop, 15); @@ -1173,200 +924,268 @@ void Mult_v2::animate(void) { _vm->_scenery->_toRedrawRight, _vm->_scenery->_toRedrawTop, _vm->_scenery->_toRedrawRight, _vm->_scenery->_toRedrawBottom, 15); } - animObj1->lastLeft = _vm->_scenery->_toRedrawLeft; - animObj1->lastRight = _vm->_scenery->_toRedrawRight; - animObj1->lastTop = _vm->_scenery->_toRedrawTop; - animObj1->lastBottom = _vm->_scenery->_toRedrawBottom; + animObj1.lastLeft = _vm->_scenery->_toRedrawLeft; + animObj1.lastRight = _vm->_scenery->_toRedrawRight; + animObj1.lastTop = _vm->_scenery->_toRedrawTop; + animObj1.lastBottom = _vm->_scenery->_toRedrawBottom; } else - animObj1->lastLeft = -1; + animObj1.lastLeft = -1; } else { - _vm->_scenery->_toRedrawLeft = animObj1->somethingLeft; - _vm->_scenery->_toRedrawRight = animObj1->somethingRight; - _vm->_scenery->_toRedrawTop = animObj1->somethingTop; - _vm->_scenery->_toRedrawBottom = animObj1->somethingBottom; + _vm->_scenery->_toRedrawLeft = animObj1.newLeft; + _vm->_scenery->_toRedrawRight = animObj1.newRight; + _vm->_scenery->_toRedrawTop = animObj1.newTop; + _vm->_scenery->_toRedrawBottom = animObj1.newBottom; } - _vm->_scenery->updateStatic(animObj1->pAnimData->order + 1); + _vm->_scenery->updateStatic(animData1.order + 1); } - for (i = 0; i < numAnims; i++) { - animObj1 = _renderData2[i]; - animData1 = animObj1->pAnimData; - if (animData1->isStatic != 0) + // Advance animations + for (int i = 0; i < numAnims; i++) { + Mult_Object &animObj = *_renderObjs[i]; + Mult_AnimData &animData = *(animObj.pAnimData); + + if (animData.isStatic) continue; - if ((animData1->animType == 7) && (animData1->field_F != -1)) { - animData1->layer = animData1->field_F; - animData1->frame = 0; - animData1->field_F = -1; - animData1->isPaused = 0; + if ((animData.animType == 7) && (animData.newState != -1)) { + animData.layer = animData.newState; + animData.frame = 0; + animData.newState = -1; + animData.isPaused = 0; } - if (animData1->isPaused != 0) + if (animData.isPaused) continue; - if (animData1->maxTick == animObj1->tick) { - animObj1->tick = 0; - if ((animData1->animType < 100) || (_vm->_goblin->_gobsCount < 0)) { - if (animData1->animType == 4) { - animData1->frame = 0; - animData1->isPaused = 1; - } - else { - if (animData1->animType != 8) - animData1->frame++; - if (animData1->frame >= - _vm->_scenery->_animations[(int)animData1->animation].layers[animData1->layer].framesCount) { - switch (animData1->animType) { - case 0: - animData1->frame = 0; - break; - - case 1: - animData1->frame = 0; - *(animObj1->pPosX) += - _vm->_scenery->_animations[(int)animData1->animation].layers[animData1->layer].animDeltaX; - *(animObj1->pPosY) += - _vm->_scenery->_animations[(int)animData1->animation].layers[animData1->layer].animDeltaY; - break; - - case 2: - animData1->frame = 0; - animData1->animation = animData1->newAnimation; - animData1->layer = animData1->newLayer; - break; - - case 3: - animData1->animType = 4; - animData1->frame = 0; - break; - - case 5: - animData1->isStatic = 1; - animData1->frame = 0; - break; - - case 6: - case 7: - animData1->frame--; - animData1->isPaused = 1; - break; - } - animData1->newCycle = 1; - } else - animData1->newCycle = 0; - } - } - else if (animData1->animType == 100) - _vm->_goblin->moveAdvance(animObj1, 0, 0, 0); - else if (animData1->animType == 101) - _vm->_goblin->sub_11984(animObj1); + if (animData.maxTick == animObj.tick) { + animObj.tick = 0; + if ((animData.animType < 100) || (_vm->_goblin->_gobsCount < 0)) + newCycleAnim(animObj); + else if (animData.animType == 100) + _vm->_goblin->moveAdvance(&animObj, 0, 0, 0); + else if (animData.animType == 101) + _vm->_goblin->animate(&animObj); } else - animObj1->tick++; + animObj.tick++; } - for (i = 0; i < numAnims; i++) { - animObj1 = _renderData2[i]; - animData1 = animObj1->pAnimData; - if ((animData1->isStatic == 0) && (animObj1->lastLeft != -1)) - for (j = 0; j < numAnims; j++) { - animObj2 = _renderData2[j]; - animData2 = animObj2->pAnimData; - if ((i != j) && (animData2->isStatic == 0) && (animObj2->lastLeft != -1)) - if ((animObj2->lastRight >= animObj1->lastLeft) && - (animObj2->lastLeft <= animObj1->lastRight) && - (animObj2->lastBottom >= animObj1->lastTop) && - (animObj2->lastTop <= animObj1->lastBottom)) - animData2->intersected = animIndices[i]; - } - } + // Find intersections + for (int i = 0; i < numAnims; i++) { + Mult_Object &animObj1 = *_renderObjs[i]; + Mult_AnimData &animData1 = *(animObj1.pAnimData); -} + if (animData1.isStatic || (animObj1.lastLeft == -1)) + continue; -void Mult_v2::playSound(Snd::SoundDesc * soundDesc, int16 repCount, int16 freq, - int16 fadeLength) { - _vm->_snd->playSample(soundDesc, repCount, freq, fadeLength); -} + for (int j = 0; j < numAnims; j++) { + Mult_Object &animObj2 = *_renderObjs[i]; + Mult_AnimData &animData2 = *(animObj2.pAnimData); -void Mult_v2::freeMult(void) { - if ((_vm->_anim->_animSurf != 0) && (_vm->_draw->_spritesArray[22] != 0)) - _vm->_video->freeSurfDesc(_vm->_anim->_animSurf); - _vm->_anim->_animSurf = 0; - _vm->_draw->_spritesArray[22] = 0; + if (i == j) + continue; + if ((animData2.isStatic) || (animObj2.lastLeft == -1)) + continue; - delete[] _objects; - delete[] _renderData2; - delete[] _orderArray; + if ((animObj2.lastRight >= animObj1.lastLeft) && + (animObj2.lastLeft <= animObj1.lastRight) && + (animObj2.lastBottom >= animObj1.lastTop) && + (animObj2.lastTop <= animObj1.lastBottom)) + animData2.intersected = animIndices[i]; + } + } - _objects = 0; - _renderData2 = 0; - _orderArray = 0; } -void Mult_v2::freeMultKeys(void) { - int i; - char animCount; - char staticCount; +void Mult_v2::playImd(char *imdFile, Mult::Mult_ImdKey &key, int16 dir, + int16 startFrame) { + int16 x, y; + int16 repeat = 0; + int16 palStart, palEnd; + int16 lastFrame; + uint16 flags; + int16 di; + int16 var_6; - if (_multData == 0) + if (_vm->_draw->_renderFlags & 0x100) { + x = VAR(55); + y = VAR(56); + } else + x = y = -1; + + if (key.imdFile == -1) { + _vm->_imdPlayer->closeImd(); return; + } - staticCount = (_multData->staticCount + 1) & 0x7F; - animCount = _multData->animCount + 1; + flags = (key.flags >> 8) & 0xFF; + if (flags & 0x20) + flags = (flags & 0x9F) | 0x80; - for (i = 0; i < staticCount; i++) { // loc_7345 - if (_multData->staticLoaded[i] != 0) - _vm->_scenery->freeStatic(_multData->staticIndices[i]); - } + palStart = key.palStart; + palEnd = key.palEnd; + di = key.field_A; + lastFrame = key.lastFrame; - for (i = 0; i < animCount; i++) { // loc_7377 - if (_multData->animLoaded[i] != 0) - _vm->_scenery->freeAnim(_multData->animIndices[i]); - } + if ((di == -1) && (lastFrame == -1)) + if (startFrame > 0) + if (!(key.flags & 0x4000)) { + _vm->_imdPlayer->closeImd(); + return; + } - delete[] _multData->staticKeys; + if (!_vm->_imdPlayer->openImd(imdFile, x, y, repeat, flags)) + return; - for (i = 0; i < 4; i++) { // loc_73BA - delete[] _multData->animKeys[i]; - if (_multData->someKeys[i] != 0) - delete[] _multData->someKeys[i]; - } + if (di == -1) + di = 0; + if (lastFrame == -1) + lastFrame = _vm->_imdPlayer->_curImd->framesCount - 1; - delete[] _multData->palFadeKeys; - delete[] _multData->palKeys; - delete[] _multData->textKeys; + var_6 = startFrame % (lastFrame - di + 1); + _vm->_imdPlayer->play(var_6 + di, flags & 0x7F, palStart, palEnd, di, lastFrame); +} - for (i = 0; i < _multData->sndSlotsCount; i++) { // loc_7448 - if ((_multData->sndSlot[i] & 0x8000) == 0) - _vm->_game->freeSoundSlot(_multData->sndSlot[i]); - } +void Mult_v2::advanceObjects(int16 index) { + int16 frame; + bool stop = false; - delete[] _multData->sndKeys; + frame = _multData->animKeysFrames[index]; + if (frame == -1) + return; - if (_multData->somepointer09 != 0) - delete[] _multData->somepointer09; - if (_multData->somepointer10 != 0) - delete[] _multData->somepointer10; + for (int i = 0; i < 4; i++) { + if (_multData->animObjs[index][i] != -1) { + int keyIndex = _multData->animKeysIndices[index][i]; + int count = _multData->animKeysCount[i]; - if (_animDataAllocated != 0) { - freeMult(); - - delete[] _animArrayX; - _animArrayX = 0; + for (int j = keyIndex; j < count; j++) { + Mult_AnimKey &key = _multData->animKeys[i][j]; + Mult_Object &animObj = _objects[_multData->animObjs[index][i]]; + Mult_AnimData &animData = *(animObj.pAnimData); - delete[] _animArrayY; - _animArrayY = 0; + if (key.frame > frame) + break; + else if (key.frame < frame) + continue; - delete[] _animArrayData; - _animArrayData = 0; + if (key.layer > -1) { + int16 layer; + int16 layers; + int16 curAnim; + + _multData->animKeysIndices[index][i] = j; + *(animObj.pPosX) = key.posX; + *(animObj.pPosY) = key.posY; + animData.frame = 0; + animData.animType = 1; + animData.isStatic = 0; + animData.isPaused = 0; + animData.maxTick = 0; + animData.animation = 0; + animObj.tick = 0; + + curAnim = _multData->animIndices[0]; + layer = key.layer; + layers = _vm->_scenery->getAnimLayersCount(curAnim); + while (layer >= layers) { + layer -= layers; + animData.animation++; + curAnim = _multData->animIndices[animData.animation]; + layers = _vm->_scenery->getAnimLayersCount(curAnim); + } + animData.layer = layer; + animData.animation = + _multData->animIndices[animData.animation]; + break; + } else + animData.isStatic = 1; + } + } + + if (_multData->animObjs[index][i] != -1) { + int keyIndex = _multData->imdKeysIndices[index][i]; + int count = _multData->imdKeysCount[i]; - _animDataAllocated = 0; + for (int j = keyIndex; j < count; j++) { + Mult_ImdKey &key1 = _multData->imdKeys[i][j]; + Mult_ImdKey &key2 = _multData->imdKeys[i][j - 1]; + + if (key1.frame > frame) + break; + else if (key1.frame < frame) + continue; + + if (key1.imdFile != -1) { + _multData->imdIndices[0] = -1; + _multData->imdIndices[1] = -1; + _multData->imdIndices[2] = -1; + _multData->imdIndices[3] = -1; + if ((_multData->animDirection == 1) || (key2.imdFile == 1)) + _multData->imdIndices[i] = j; + else if (_multData->animKeysStopFrames[index] == frame) + _multData->imdIndices[i] = -1; + else + _multData->imdIndices[i] = j - 1; + } else + _multData->imdIndices[i] = -1; + } + } + + if (_multData->imdIndices[i] != -1) { + int fileN; + char *imdFile; + int dir; + int startFrame; + + fileN = -_multData->imdKeys[i][_multData->imdIndices[i]].imdFile - 2; + if (fileN < 0) + return; + + Mult_ImdKey &key = _multData->imdKeys[i][_multData->imdIndices[i]]; + + dir = _multData->animDirection; + startFrame = frame - key.frame; + if ((dir != 1) && (--startFrame > 0)) + startFrame = 0; + + playImd(imdFile, key, dir, startFrame); + } } + + doSoundAnim(stop, frame); + WRITE_VAR(22, frame); - for (i = 0; i < 8; i++) - if (_multDatas[i] == _multData) - _multDatas[i] = 0; + if (_multData->animKeysStopFrames[index] == frame) { + _multData->imdIndices[0] = -1; + _multData->imdIndices[1] = -1; + _multData->imdIndices[2] = -1; + _multData->imdIndices[3] = -1; + frame = -1; + for (int i = 0; i < 4; i++) { + int obj = _multData->animObjs[index][i]; - delete _multData; - _multData = 0; + if ((obj == -1) || (obj == 1024)) + continue; + + Mult_Object &animObj = _objects[_multData->animObjs[index][i]]; + animObj.pAnimData->animType = animObj.pAnimData->animTypeBak; + } + } else if (_multData->animDirection == 1) + frame++; + else + frame--; + + _multData->animKeysFrames[index] = frame; + WRITE_VAR(18 + index, frame); +} + +void Mult_v2::advanceAllObjects() { + for (int i = 0; i < 8; i++) { + if (_multDatas[i]) { + _multData = _multDatas[i]; + for (int j = 0; j < 4; j++) + advanceObjects(j); + } + } } } // End of namespace Gob diff --git a/engines/gob/music.cpp b/engines/gob/music.cpp index 67608bcd67..b12284a05f 100644 --- a/engines/gob/music.cpp +++ b/engines/gob/music.cpp @@ -25,8 +25,8 @@ #include "common/stdafx.h" #include "common/endian.h" -#include "gob/music.h" #include "gob/gob.h" +#include "gob/music.h" #include "gob/game.h" #include "gob/util.h" @@ -97,7 +97,7 @@ Adlib::Adlib(GobEngine *vm) : _vm(vm) { this, -1, 255, 0, false, true); } -Adlib::~Adlib(void) { +Adlib::~Adlib() { Common::StackLock slock(_mutex); _vm->_mixer->stopHandle(_handle); @@ -163,7 +163,7 @@ void Adlib::writeOPL(byte reg, byte val) { OPLWriteReg(_opl, reg, val); } -void Adlib::setFreqs(void) { +void Adlib::setFreqs() { byte lin; byte col; long val = 0; @@ -308,7 +308,7 @@ void Adlib::setKey(byte voice, byte note, bool on, bool spec) { octa = note / 12; freq = _freqs[_notLin[voice]][note - octa * 12]; - writeOPL(0xA0 + voice, freq & 0xff); + writeOPL(0xA0 + voice, freq & 0xFF); writeOPL(0xB0 + voice, (freq >> 8) | (octa << 2) | 0x20 * on); if (!freq) @@ -320,14 +320,14 @@ void Adlib::setVolume(byte voice, byte volume) { writeOPL(0x40 + _volRegNums[voice], volume); } -void Adlib::pollMusic(void) { +void Adlib::pollMusic() { unsigned char instr; byte channel; byte note; byte volume; uint16 tempo; - if ((_playPos > (_data + _dataSize)) && (_dataSize != (uint32) -1)) { + if ((_playPos > (_data + _dataSize)) && (_dataSize != 0xFFFFFFFF)) { _ended = true; return; } @@ -417,7 +417,7 @@ void Adlib::pollMusic(void) { _samplesTillPoll = tempo * (_rate / 1000); } -void Adlib::playBgMusic(void) { +void Adlib::playBgMusic() { for (int i = 0; i < ARRAYSIZE(_tracks); i++) if (!scumm_stricmp(_vm->_game->_curTotFile, _tracks[i][0])) { playTrack(_tracks[i][1]); @@ -434,11 +434,11 @@ void Adlib::playTrack(const char *trackname) { startPlay(); } -bool Adlib::load(const char *filename) { +bool Adlib::load(const char *fileName) { Common::File song; unload(); - song.open(filename); + song.open(fileName); if (!song.isOpen()) return false; @@ -455,11 +455,11 @@ bool Adlib::load(const char *filename) { return true; } -void Adlib::load(byte *data, int index) { +void Adlib::load(byte *data, uint32 size, int index) { unload(); _repCount = 0; - _dataSize = (uint32) -1; + _dataSize = size; _data = data; _index = index; @@ -468,7 +468,7 @@ void Adlib::load(byte *data, int index) { _playPos = _data + 3 + (_data[1] + 1) * 0x38; } -void Adlib::unload(void) { +void Adlib::unload() { _playing = false; _index = -1; diff --git a/engines/gob/music.h b/engines/gob/music.h index 89d3d7acf4..2531f36e4a 100644 --- a/engines/gob/music.h +++ b/engines/gob/music.h @@ -24,13 +24,10 @@ #ifndef GOB_MUSIC_H #define GOB_MUSIC_H +#include "common/mutex.h" #include "sound/audiostream.h" #include "sound/mixer.h" #include "sound/fmopl.h" -#include "common/mutex.h" - -#include "gob/gob.h" -#include "gob/util.h" namespace Gob { @@ -44,20 +41,20 @@ public: void lock() { _mutex.lock(); } void unlock() { _mutex.unlock(); } bool playing() const { return _playing; } - bool getRepeating(void) const { return _repCount != 0; } + bool getRepeating() const { return _repCount != 0; } void setRepeating (int32 repCount) { _repCount = repCount; } - int getIndex(void) const { return _index; } - virtual void startPlay(void) { if (_data) _playing = true; } - virtual void stopPlay(void) + int getIndex() const { return _index; } + void startPlay() { if (_data) _playing = true; } + void stopPlay() { Common::StackLock slock(_mutex); _playing = false; } - virtual void playTrack(const char *trackname); - virtual void playBgMusic(void); - virtual bool load(const char *filename); - virtual void load(byte *data, int index=-1); - virtual void unload(void); + void playTrack(const char *trackname); + void playBgMusic(); + bool load(const char *fileName); + void load(byte *data, uint32 size, int index = -1); + void unload(); // AudioStream API int readBuffer(int16 *buffer, const int numSamples); @@ -94,15 +91,15 @@ protected: GobEngine *_vm; void writeOPL(byte reg, byte val); - void setFreqs(void); - void reset(void); + void setFreqs(); + void reset(); void setVoices(); void setVoice(byte voice, byte instr, bool set); void setKey(byte voice, byte note, bool on, bool spec); void setVolume(byte voice, byte volume); - void pollMusic(void); + void pollMusic(); }; } // End of namespace Gob -#endif +#endif // GOB_MUSIC_H diff --git a/engines/gob/pack.cpp b/engines/gob/pack.cpp deleted file mode 100644 index 60ba5deea4..0000000000 --- a/engines/gob/pack.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004 Ivan Dubrov - * Copyright (C) 2004-2006 The ScummVM project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "common/stdafx.h" -#include "common/endian.h" - -#include "gob/gob.h" -#include "gob/pack.h" - -namespace Gob { - -int32 Pack::unpackData(char *sourceBuf, char *destBuf) { - uint32 realSize; - uint32 counter; - uint16 cmd; - byte *src; - byte *dest; - byte *tmpBuf; - int16 off; - byte len; - byte i; - int16 j; - uint16 tmpIndex; - - realSize = READ_LE_UINT32(sourceBuf); - counter = READ_LE_UINT32(sourceBuf); - - tmpBuf = new byte[4114]; - - /* - * Can use assembler unpacker for small blocks - for speed. - * Don't need this anymore :) - */ - /* - * if (realSize < 65000) - * { - * asm_unpackData(sourceBuf, destBuf, tmpBuf); - * free(tmpBuf); - * return realSize; - * } - */ - - if (tmpBuf == 0) - return 0; - - for (j = 0; j < 4078; j++) - tmpBuf[j] = 0x20; - tmpIndex = 4078; - - src = (byte *)(sourceBuf + 4); - dest = (byte *)destBuf; - - cmd = 0; - while (1) { - cmd >>= 1; - if ((cmd & 0x0100) == 0) { - cmd = *src | 0xff00; - src++; - } - if ((cmd & 1) != 0) { /* copy */ - *dest++ = *src; - tmpBuf[tmpIndex] = *src; - src++; - tmpIndex++; - tmpIndex %= 4096; - counter--; - if (counter == 0) - break; - } else { /* copy string */ - - off = *src++; - off |= (*src & 0xf0) << 4; - len = (*src & 0x0f) + 3; - src++; - for (i = 0; i < len; i++) { - *dest++ = tmpBuf[(off + i) % 4096]; - counter--; - if (counter == 0) { - delete[] tmpBuf; - return realSize; - } - tmpBuf[tmpIndex] = tmpBuf[(off + i) % 4096]; - tmpIndex++; - tmpIndex %= 4096; - } - } - } - delete[] tmpBuf; - return realSize; -} - -} // End of namespace Gob diff --git a/engines/gob/pack.h b/engines/gob/pack.h deleted file mode 100644 index 9df0d97b24..0000000000 --- a/engines/gob/pack.h +++ /dev/null @@ -1,36 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004 Ivan Dubrov - * Copyright (C) 2004-2006 The ScummVM project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ -#ifndef GOB_UNPACKER_H -#define GOB_UNPACKER_H - -namespace Gob { - -class Pack { -public: - int32 asm_unpackData(char *source, char *dest, char *temp); - int32 unpackData(char *source, char *dest); -}; - -} // End of namespace Gob - -#endif diff --git a/engines/gob/palanim.cpp b/engines/gob/palanim.cpp index 1160b6d2ac..e2290c0244 100644 --- a/engines/gob/palanim.cpp +++ b/engines/gob/palanim.cpp @@ -20,11 +20,12 @@ * $Id$ * */ + #include "gob/gob.h" -#include "gob/video.h" -#include "gob/util.h" -#include "gob/global.h" #include "gob/palanim.h" +#include "gob/global.h" +#include "gob/util.h" +#include "gob/video.h" namespace Gob { @@ -35,128 +36,112 @@ PalAnim::PalAnim(GobEngine *vm) : _vm(vm) { _toFadeGreen[i] = 0; _toFadeBlue[i] = 0; } + + _palArray[0] = _vm->_global->_redPalette; + _palArray[1] = _vm->_global->_greenPalette; + _palArray[2] = _vm->_global->_bluePalette; + _fadeArray[0] = _toFadeRed; + _fadeArray[1] = _toFadeGreen; + _fadeArray[2] = _toFadeBlue; } -char PalAnim::fadeColor(char from, char to) { - if ((int16)from - _fadeValue > (int16)to) +char PalAnim::fadeColor(int16 from, int16 to) { + if ((from - _fadeValue) > to) return from - _fadeValue; - else if ((int16)from + _fadeValue < (int16)to) + else if ((from + _fadeValue) < to) return from + _fadeValue; - else - return to; + else return to; } -char PalAnim::fadeStep(int16 oper) { +bool PalAnim::fadeStepColor(int color) { + bool stop = true; + char colors[3]; + + for (int i = 0; i < 16; i++) { + colors[0] = _palArray[0][i]; + colors[1] = _palArray[1][i]; + colors[2] = _palArray[2][i]; + colors[color] = fadeColor(_palArray[color][i], _fadeArray[color][i]); + + _vm->_video->setPalElem(i, colors[0], colors[1], colors[2], + -1, _vm->_global->_videoMode); + + if (_palArray[color][i] != _fadeArray[color][i]) + stop = false; + } + + return stop; +} + +bool PalAnim::fadeStep(int16 oper) { + bool stop = true; byte newRed; byte newGreen; byte newBlue; - char stop; - int16 i; if (_vm->_global->_colorCount != 256) error("fadeStep: Only 256 color mode is supported!"); if (oper == 0) { - stop = 1; if (_vm->_global->_setAllPalette) { if (_vm->_global->_inVM != 0) error("fade: _vm->_global->_inVM != 0 not supported."); - for (i = 0; i < 256; i++) { + for (int i = 0; i < 256; i++) { newRed = fadeColor(_vm->_global->_redPalette[i], _toFadeRed[i]); newGreen = fadeColor(_vm->_global->_greenPalette[i], _toFadeGreen[i]); newBlue = fadeColor(_vm->_global->_bluePalette[i], _toFadeBlue[i]); - if (_vm->_global->_redPalette[i] != newRed - || _vm->_global->_greenPalette[i] != newGreen - || _vm->_global->_bluePalette[i] != newBlue) { + if ((_vm->_global->_redPalette[i] != newRed) || + (_vm->_global->_greenPalette[i] != newGreen) || + (_vm->_global->_bluePalette[i] != newBlue)) { _vm->_video->setPalElem(i, newRed, newGreen, newBlue, 0, 0x13); _vm->_global->_redPalette[i] = newRed; _vm->_global->_greenPalette[i] = newGreen; _vm->_global->_bluePalette[i] = newBlue; - stop = 0; + stop = false; } } } else { - for (i = 0; i < 16; i++) { + for (int i = 0; i < 16; i++) { _vm->_video->setPalElem(i, - fadeColor(_vm->_global->_redPalette[i], - _toFadeRed[i]), - fadeColor(_vm->_global->_greenPalette[i], - _toFadeGreen[i]), - fadeColor(_vm->_global->_bluePalette[i], - _toFadeBlue[i]), -1, _vm->_global->_videoMode); - - if (_vm->_global->_redPalette[i] != _toFadeRed[i] || - _vm->_global->_greenPalette[i] != _toFadeGreen[i] || - _vm->_global->_bluePalette[i] != _toFadeBlue[i]) - stop = 0; + fadeColor(_vm->_global->_redPalette[i], _toFadeRed[i]), + fadeColor(_vm->_global->_greenPalette[i], _toFadeGreen[i]), + fadeColor(_vm->_global->_bluePalette[i], _toFadeBlue[i]), + -1, _vm->_global->_videoMode); + + if ((_vm->_global->_redPalette[i] != _toFadeRed[i]) || + (_vm->_global->_greenPalette[i] != _toFadeGreen[i]) || + (_vm->_global->_bluePalette[i] != _toFadeBlue[i])) + stop = false; } } - return stop; - } else if (oper == 1) { - stop = 1; - for (i = 0; i < 16; i++) { - _vm->_video->setPalElem(i, - fadeColor(_vm->_global->_redPalette[i], _toFadeRed[i]), - _vm->_global->_greenPalette[i], _vm->_global->_bluePalette[i], -1, _vm->_global->_videoMode); - - if (_vm->_global->_redPalette[i] != _toFadeRed[i]) - stop = 0; - } - return stop; - } else if (oper == 2) { - stop = 1; - for (i = 0; i < 16; i++) { - _vm->_video->setPalElem(i, - _vm->_global->_redPalette[i], - fadeColor(_vm->_global->_greenPalette[i], _toFadeGreen[i]), - _vm->_global->_bluePalette[i], -1, _vm->_global->_videoMode); - - if (_vm->_global->_greenPalette[i] != _toFadeGreen[i]) - stop = 0; - } - return stop; - } else if (oper == 3) { - stop = 1; - for (i = 0; i < 16; i++) { - _vm->_video->setPalElem(i, - _vm->_global->_redPalette[i], - _vm->_global->_greenPalette[i], - fadeColor(_vm->_global->_bluePalette[i], _toFadeBlue[i]), - -1, _vm->_global->_videoMode); - - if (_vm->_global->_bluePalette[i] != _toFadeBlue[i]) - stop = 0; - } - return stop; - } - return 1; + } else if ((oper > 0) && (oper < 4)) + stop = fadeStepColor(oper - 1); + + return stop; } void PalAnim::fade(Video::PalDesc *palDesc, int16 fadeV, int16 allColors) { - char stop; + bool stop; int16 i; if (_vm->_quitRequested) return; - if (fadeV < 0) - _fadeValue = -fadeV; - else - _fadeValue = 2; + _fadeValue = (fadeV < 0) ? -fadeV : 2; if (_vm->_global->_colorCount < 256) { - if (palDesc != 0) + if (palDesc) _vm->_video->setFullPalette(palDesc); return; } - if (_vm->_global->_setAllPalette == 0) { - if (palDesc == 0) { + if (!_vm->_global->_setAllPalette) { + if (!palDesc) { for (i = 0; i < 16; i++) { _toFadeRed[i] = 0; _toFadeGreen[i] = 0; @@ -173,7 +158,7 @@ void PalAnim::fade(Video::PalDesc *palDesc, int16 fadeV, int16 allColors) { if (_vm->_global->_inVM != 0) error("fade: _vm->_global->_inVM != 0 is not supported"); - if (palDesc == 0) { + if (!palDesc) { for (i = 0; i < 256; i++) { _toFadeRed[i] = 0; _toFadeGreen[i] = 0; @@ -195,9 +180,9 @@ void PalAnim::fade(Video::PalDesc *palDesc, int16 fadeV, int16 allColors) { if (fadeV > 0) _vm->_util->delay(fadeV); - } while (stop == 0); + } while (!stop); - if (palDesc != 0) + if (palDesc) _vm->_video->setFullPalette(palDesc); else _vm->_util->clearPalette(); @@ -207,23 +192,23 @@ void PalAnim::fade(Video::PalDesc *palDesc, int16 fadeV, int16 allColors) { do { _vm->_video->waitRetrace(_vm->_global->_videoMode); stop = fadeStep(1); - } while (stop == 0); + } while (!stop); do { _vm->_video->waitRetrace(_vm->_global->_videoMode); stop = fadeStep(2); - } while (stop == 0); + } while (!stop); do { _vm->_video->waitRetrace(_vm->_global->_videoMode); stop = fadeStep(3); - } while (stop == 0); + } while (!stop); - if (palDesc != 0) + if (palDesc) _vm->_video->setFullPalette(palDesc); else _vm->_util->clearPalette(); } } -} // End of namespace Gob +} // End of namespace Gob diff --git a/engines/gob/palanim.h b/engines/gob/palanim.h index 8bc661a052..81c480cd3e 100644 --- a/engines/gob/palanim.h +++ b/engines/gob/palanim.h @@ -20,15 +20,17 @@ * $Id$ * */ + #ifndef GOB_PALANIM_H #define GOB_PALANIM_H +#include "gob/video.h" + namespace Gob { class PalAnim { public: - char fadeColor(char from, char to); - char fadeStep(int16 oper); // oper == 0 - fade all colors, 1, 2, 3 - red,green, blue + bool fadeStep(int16 oper); // 0: all colors, 1: red, 2: green, 3: blue void fade(Video::PalDesc * palDesc, int16 fade, int16 all); PalAnim(GobEngine *vm); @@ -39,9 +41,16 @@ protected: byte _toFadeRed[256]; byte _toFadeGreen[256]; byte _toFadeBlue[256]; + + char *_palArray[3]; + byte *_fadeArray[3]; + GobEngine *_vm; + + bool fadeStepColor(int color); + char fadeColor(int16 from, int16 to); }; -} // End of namespace Gob +} // End of namespace Gob -#endif /* __PALANIM_H */ +#endif // GOB_PALANIM_H diff --git a/engines/gob/parse.cpp b/engines/gob/parse.cpp index 14fec542fb..8c095b56a7 100644 --- a/engines/gob/parse.cpp +++ b/engines/gob/parse.cpp @@ -25,10 +25,9 @@ #include "common/endian.h" #include "gob/gob.h" +#include "gob/parse.h" #include "gob/global.h" #include "gob/game.h" -#include "gob/parse.h" -#include "gob/util.h" #include "gob/inter.h" namespace Gob { @@ -85,7 +84,7 @@ void Parse::skipExpr(char stopToken) { while (1) { operation = *_vm->_global->_inter_execPtr++; - if (operation >= 16 && operation <= 29) { + if ((operation >= 16) && (operation <= 29)) { switch (operation) { case 17: case 18: @@ -104,7 +103,8 @@ void Parse::skipExpr(char stopToken) { break; case 22: - _vm->_global->_inter_execPtr += strlen(_vm->_global->_inter_execPtr) + 1; + _vm->_global->_inter_execPtr += + strlen(_vm->_global->_inter_execPtr) + 1; break; case 25: @@ -126,7 +126,7 @@ void Parse::skipExpr(char stopToken) { for (dim = 0; dim < dimCount; dim++) skipExpr(12); - if (operation == 28 && *_vm->_global->_inter_execPtr == 13) { + if ((operation == 28) && (*_vm->_global->_inter_execPtr == 13)) { _vm->_global->_inter_execPtr++; skipExpr(12); } @@ -137,17 +137,17 @@ void Parse::skipExpr(char stopToken) { skipExpr(10); } continue; - } // if (operation >= 16 && operation <= 29) + } // if ((operation >= 16) && (operation <= 29)) if (operation == 9) { num++; continue; } - if (operation == 11 || (operation >= 1 && operation <= 8)) + if ((operation == 11) || ((operation >= 1) && (operation <= 8))) continue; - if (operation >= 30 && operation <= 37) + if ((operation >= 30) && (operation <= 37)) continue; if (operation == 10) @@ -156,7 +156,7 @@ void Parse::skipExpr(char stopToken) { if (operation != stopToken) continue; - if (stopToken != 10 || num < 0) + if ((stopToken != 10) || (num < 0)) return; } } @@ -184,7 +184,7 @@ void Parse::printExpr_internal(char stopToken) { while (1) { operation = *_vm->_global->_inter_execPtr++; - if (operation >= 16 && operation <= 29) { + if ((operation >= 16) && (operation <= 29)) { // operands switch (operation) { @@ -211,7 +211,8 @@ void Parse::printExpr_internal(char stopToken) { case 22: // string immediate debugN(5, "\42%s\42", _vm->_global->_inter_execPtr); - _vm->_global->_inter_execPtr += strlen(_vm->_global->_inter_execPtr) + 1; + _vm->_global->_inter_execPtr += + strlen(_vm->_global->_inter_execPtr) + 1; break; case 23: // uint32 variable load @@ -250,7 +251,7 @@ void Parse::printExpr_internal(char stopToken) { if (operation == 28) debugN(5, ")"); - if (operation == 28 && *_vm->_global->_inter_execPtr == 13) { + if ((operation == 28) && (*_vm->_global->_inter_execPtr == 13)) { _vm->_global->_inter_execPtr++; debugN(5, "{"); printExpr_internal(12); // this also prints the closing } @@ -265,7 +266,7 @@ void Parse::printExpr_internal(char stopToken) { debugN(5, "rand("); else if (func == 7) debugN(5, "abs("); - else if (func == 0 || func == 1 || func == 6) + else if ((func == 0) || (func == 1) || (func == 6)) debugN(5, "sqrt("); else debugN(5, "id("); @@ -273,7 +274,7 @@ void Parse::printExpr_internal(char stopToken) { break; } continue; - } // if (operation >= 16 && operation <= 29) + } // if ((operation >= 16) && (operation <= 29)) // operators switch (operation) { @@ -365,7 +366,7 @@ void Parse::printExpr_internal(char stopToken) { break; default: - debugN(5, "<%d>", (int16)operation); + debugN(5, "<%d>", (int16) operation); error("printExpr: invalid operator in expression"); break; } @@ -375,17 +376,17 @@ void Parse::printExpr_internal(char stopToken) { continue; } - if (operation == 11 || (operation >= 1 && operation <= 8)) + if ((operation == 11) || ((operation >= 1) && (operation <= 8))) continue; - if (operation >= 30 && operation <= 37) + if ((operation >= 30) && (operation <= 37)) continue; if (operation == 10) num--; if (operation == stopToken) { - if (stopToken != 10 || num < 0) { + if ((stopToken != 10) || (num < 0)) { return; } } @@ -408,7 +409,7 @@ void Parse::printVarIndex() { case 25: temp = _vm->_inter->load16() * 4; debugN(5, "&var_%d", temp); - if (operation == 25 && *_vm->_global->_inter_execPtr == 13) { + if ((operation == 25) && (*_vm->_global->_inter_execPtr == 13)) { _vm->_global->_inter_execPtr++; debugN(5, "+"); printExpr(12); @@ -429,7 +430,7 @@ void Parse::printVarIndex() { } debugN(5, "]"); - if (operation == 28 && *_vm->_global->_inter_execPtr == 13) { + if ((operation == 28) && (*_vm->_global->_inter_execPtr == 13)) { _vm->_global->_inter_execPtr++; debugN(5, "+"); printExpr(12); diff --git a/engines/gob/parse.h b/engines/gob/parse.h index 2ebcdfb2ec..be7ae6c9ac 100644 --- a/engines/gob/parse.h +++ b/engines/gob/parse.h @@ -20,6 +20,7 @@ * $Id$ * */ + #ifndef GOB_PARSE_H #define GOB_PARSE_H @@ -31,7 +32,7 @@ public: void printExpr(char stopToken); void printVarIndex(void); virtual int16 parseVarIndex(void) = 0; - virtual int16 parseValExpr(unsigned stopToken=99) = 0; + virtual int16 parseValExpr(unsigned stopToken = 99) = 0; virtual int16 parseExpr(char stopToken, byte *resultPtr) = 0; Parse(GobEngine *vm); @@ -72,6 +73,6 @@ public: virtual int16 parseExpr(char stopToken, byte *resultPtr); }; -} // End of namespace Gob +} // End of namespace Gob -#endif +#endif // GOB_PARSE_H diff --git a/engines/gob/parse_v1.cpp b/engines/gob/parse_v1.cpp index 379f4601eb..23363dfc9a 100644 --- a/engines/gob/parse_v1.cpp +++ b/engines/gob/parse_v1.cpp @@ -26,8 +26,8 @@ #include "gob/gob.h" #include "gob/parse.h" -#include "gob/inter.h" #include "gob/global.h" +#include "gob/inter.h" namespace Gob { @@ -50,8 +50,10 @@ int16 Parse_v1::parseVarIndex() { case 23: case 25: temp = _vm->_inter->load16() * 4; - debugC(5, kDebugParser, "oper = %d", (int16)*_vm->_global->_inter_execPtr); - if (operation == 25 && *_vm->_global->_inter_execPtr == 13) { + debugC(5, kDebugParser, "oper = %d", + (int16) *_vm->_global->_inter_execPtr); + + if ((operation == 25) && (*_vm->_global->_inter_execPtr == 13)) { _vm->_global->_inter_execPtr++; val = parseValExpr(12); temp += val; @@ -118,7 +120,7 @@ int16 Parse_v1::parseValExpr(unsigned stopToken) { valPtr++; operation = *_vm->_global->_inter_execPtr++; - if (operation >= 19 && operation <= 29) { + if ((operation >= 19) && (operation <= 29)) { *operPtr = 20; switch (operation) { case 19: @@ -131,7 +133,7 @@ int16 Parse_v1::parseValExpr(unsigned stopToken) { break; case 23: - *valPtr = (uint16)VAR(_vm->_inter->load16()); + *valPtr = (uint16) VAR(_vm->_inter->load16()); break; case 25: @@ -145,7 +147,7 @@ int16 Parse_v1::parseValExpr(unsigned stopToken) { case 28: temp = _vm->_inter->load16(); dimCount = *_vm->_global->_inter_execPtr++; - arrDesc = (byte*)_vm->_global->_inter_execPtr; + arrDesc = (byte*) _vm->_global->_inter_execPtr; _vm->_global->_inter_execPtr += dimCount; offset = 0; for (dim = 0; dim < dimCount; dim++) { @@ -153,11 +155,12 @@ int16 Parse_v1::parseValExpr(unsigned stopToken) { offset = arrDesc[dim] * offset + temp2; } if (operation == 26) { - *valPtr = (uint16)VAR(temp + offset); + *valPtr = (uint16) VAR(temp + offset); } else { _vm->_global->_inter_execPtr++; temp2 = parseValExpr(12); - *valPtr = READ_VARO_UINT8(temp * 4 + offset * 4 * _vm->_global->_inter_animDataSize + temp2); + *valPtr = READ_VARO_UINT8(temp * 4 + offset * 4 * + _vm->_global->_inter_animDataSize + temp2); } break; @@ -166,18 +169,20 @@ int16 Parse_v1::parseValExpr(unsigned stopToken) { parseExpr(10, 0); if (operation == 5) { - _vm->_global->_inter_resVal = _vm->_global->_inter_resVal * _vm->_global->_inter_resVal; + _vm->_global->_inter_resVal = + _vm->_global->_inter_resVal * _vm->_global->_inter_resVal; } else if (operation == 7) { if (_vm->_global->_inter_resVal < 0) _vm->_global->_inter_resVal = -_vm->_global->_inter_resVal; } else if (operation == 10) { - _vm->_global->_inter_resVal = _vm->_util->getRandom(_vm->_global->_inter_resVal); + _vm->_global->_inter_resVal = + _vm->_util->getRandom(_vm->_global->_inter_resVal); } *valPtr = _vm->_global->_inter_resVal; break; } // switch - if (stkPos > 0 && operPtr[-1] == 1) { + if ((stkPos > 0) && (operPtr[-1] == 1)) { stkPos--; operPtr--; valPtr--; @@ -185,7 +190,7 @@ int16 Parse_v1::parseValExpr(unsigned stopToken) { valPtr[0] = -valPtr[1]; } - if (stkPos > 0 && operPtr[-1] > 4 && operPtr[-1] < 9) { + if ((stkPos > 0) && (operPtr[-1] > 4) && (operPtr[-1] < 9)) { stkPos -= 2; operPtr -= 2; valPtr -= 2; @@ -207,11 +212,11 @@ int16 Parse_v1::parseValExpr(unsigned stopToken) { valPtr[0] &= valPtr[2]; break; } - } // if (stkPos > 0 && cmdPtr[-1] > 4 && cmdPtr[-1] < 9) + } // if ((stkPos > 0) && (cmdPtr[-1] > 4) && (cmdPtr[-1] < 9)) continue; } - if (operation >= 1 && operation <= 9) { + if ((operation >= 1) && (operation <= 9)) { *operPtr = operation; continue; } @@ -224,7 +229,7 @@ int16 Parse_v1::parseValExpr(unsigned stopToken) { operPtr[-1] = operPtr[0]; valPtr[-1] = valPtr[0]; - if (stkPos > 1 && operPtr[-2] == 1) { + if ((stkPos > 1) && (operPtr[-2] == 1)) { valPtr[-2] = 20; valPtr[-2] = -valPtr[-1]; @@ -233,8 +238,7 @@ int16 Parse_v1::parseValExpr(unsigned stopToken) { valPtr--; } - if (stkPos > 2 && operPtr[-2] > 4 - && operPtr[-2] < 9) { + if ((stkPos > 2) && (operPtr[-2] > 4) && (operPtr[-2] < 9)) { stkPos -= 2; operPtr -= 2; valPtr -= 2; @@ -260,15 +264,14 @@ int16 Parse_v1::parseValExpr(unsigned stopToken) { break; } // operPtr[-2] == 9 - for (brackPos = stkPos - 2; brackPos > 0 && - operStack[brackPos] < 30 - && operStack[brackPos] != 9; brackPos--); + for (brackPos = (stkPos - 2); (brackPos > 0) && + (operStack[brackPos] < 30) && (operStack[brackPos] != 9); + brackPos--); - if (operStack[brackPos] >= 30 - || operStack[brackPos] == 9) + if ((operStack[brackPos] >= 30) || (operStack[brackPos] == 9)) brackPos++; - if (operPtr[-2] < 2 || operPtr[-2] > 8) + if ((operPtr[-2] < 2) || (operPtr[-2] > 8)) break; stkPos -= 2; @@ -300,9 +303,10 @@ int16 Parse_v1::parseValExpr(unsigned stopToken) { } if (operation != 10) { - if (operation != stopToken) { - debugC(5, kDebugParser, "stoptoken error: %d != %d", operation, stopToken); - } + if (operation != stopToken) + debugC(5, kDebugParser, "stoptoken error: %d != %d", + operation, stopToken); + flag = oldflag; return values[0]; } @@ -334,7 +338,7 @@ int16 Parse_v1::parseExpr(char stopToken, byte *arg_2) { int16 brackStart; stkPos = -1; - operPtr = (char *)(operStack - 1); + operPtr = (char *) (operStack - 1); valPtr = values - 1; while (1) { @@ -342,7 +346,7 @@ int16 Parse_v1::parseExpr(char stopToken, byte *arg_2) { operPtr++; valPtr++; operation = *_vm->_global->_inter_execPtr++; - if (operation >= 19 && operation <= 29) { + if ((operation >= 19) && (operation <= 29)) { switch (operation) { case 19: *operPtr = 20; @@ -358,7 +362,8 @@ int16 Parse_v1::parseExpr(char stopToken, byte *arg_2) { case 22: *operPtr = 22; *valPtr = encodePtr(_vm->_global->_inter_execPtr, kExecPtr); - _vm->_global->_inter_execPtr += strlen(_vm->_global->_inter_execPtr) + 1; + _vm->_global->_inter_execPtr += + strlen(_vm->_global->_inter_execPtr) + 1; break; case 23: @@ -369,7 +374,8 @@ int16 Parse_v1::parseExpr(char stopToken, byte *arg_2) { case 25: *operPtr = 22; temp = _vm->_inter->load16() * 4; - *valPtr = encodePtr(_vm->_global->_inter_variables + temp, kInterVar); + *valPtr = encodePtr(_vm->_global->_inter_variables + temp, + kInterVar); if (*_vm->_global->_inter_execPtr == 13) { _vm->_global->_inter_execPtr++; temp += parseValExpr(12); @@ -383,7 +389,7 @@ int16 Parse_v1::parseExpr(char stopToken, byte *arg_2) { *operPtr = operation - 6; temp = _vm->_inter->load16(); dimCount = *_vm->_global->_inter_execPtr++; - arrDescPtr = (byte *)_vm->_global->_inter_execPtr; + arrDescPtr = (byte *) _vm->_global->_inter_execPtr; _vm->_global->_inter_execPtr += dimCount; offset = 0; dim = 0; @@ -396,12 +402,15 @@ int16 Parse_v1::parseExpr(char stopToken, byte *arg_2) { *valPtr = VAR(temp + offset); break; } - *valPtr = encodePtr(_vm->_global->_inter_variables + temp * 4 + offset * _vm->_global->_inter_animDataSize * 4, kInterVar); + *valPtr = encodePtr(_vm->_global->_inter_variables + + temp * 4 + offset * _vm->_global->_inter_animDataSize * 4, + kInterVar); if (*_vm->_global->_inter_execPtr == 13) { _vm->_global->_inter_execPtr++; temp2 = parseValExpr(12); *operPtr = 20; - *valPtr = READ_VARO_UINT8(temp * 4 + offset * 4 * _vm->_global->_inter_animDataSize + temp2); + *valPtr = READ_VARO_UINT8(temp * 4 + + offset * 4 * _vm->_global->_inter_animDataSize + temp2); } break; @@ -411,7 +420,8 @@ int16 Parse_v1::parseExpr(char stopToken, byte *arg_2) { switch (operation) { case 5: - _vm->_global->_inter_resVal = _vm->_global->_inter_resVal * _vm->_global->_inter_resVal; + _vm->_global->_inter_resVal = + _vm->_global->_inter_resVal * _vm->_global->_inter_resVal; break; case 0: @@ -424,12 +434,13 @@ int16 Parse_v1::parseExpr(char stopToken, byte *arg_2) { prevPrevVal = prevVal; prevVal = curVal; curVal = (curVal + _vm->_global->_inter_resVal / curVal) / 2; - } while (curVal != prevVal && curVal != prevPrevVal); + } while ((curVal != prevVal) && (curVal != prevPrevVal)); _vm->_global->_inter_resVal = curVal; break; case 10: - _vm->_global->_inter_resVal = _vm->_util->getRandom(_vm->_global->_inter_resVal); + _vm->_global->_inter_resVal = + _vm->_util->getRandom(_vm->_global->_inter_resVal); break; case 7: @@ -441,7 +452,7 @@ int16 Parse_v1::parseExpr(char stopToken, byte *arg_2) { *valPtr = _vm->_global->_inter_resVal; } - if (stkPos > 0 && (operPtr[-1] == 1 || operPtr[-1] == 11)) { + if ((stkPos > 0) && ((operPtr[-1] == 1) || (operPtr[-1] == 11))) { stkPos--; operPtr--; valPtr--; @@ -503,14 +514,16 @@ int16 Parse_v1::parseExpr(char stopToken, byte *arg_2) { break; } continue; - } // op>= 19 && op <= 29 + } // (op >= 19) && (op <= 29) - if (operation == stopToken || operation == 30 || operation == 31 || operation == 10) { + if ((operation == stopToken) || (operation == 30) || + (operation == 31) || (operation == 10)) { while (stkPos >= 2) { var_1A = 0; - if (operPtr[-2] == 9 && (operation == 10 || operation == stopToken)) { + if ((operPtr[-2] == 9) && + ((operation == 10) || (operation == stopToken))) { operPtr[-2] = operPtr[-1]; - if (operPtr[-2] == 20 || operPtr[-2] == 22) + if ((operPtr[-2] == 20) || (operPtr[-2] == 22)) valPtr[-2] = valPtr[-1]; stkPos--; @@ -569,13 +582,13 @@ int16 Parse_v1::parseExpr(char stopToken, byte *arg_2) { if (operation != stopToken) break; - } // if (operPtr[-2] == 9 && ...) + } // if ((operPtr[-2] == 9) && ...) - for (brackStart = stkPos - 2; brackStart > 0 && - operStack[brackStart] < 30 && - operStack[brackStart] != 9; brackStart--); + for (brackStart = (stkPos - 2); (brackStart > 0) && + (operStack[brackStart] < 30) && (operStack[brackStart] != 9); + brackStart--); - if (operStack[brackStart] >= 30 || operStack[brackStart] == 9) + if ((operStack[brackStart] >= 30) || (operStack[brackStart] == 9)) brackStart++; switch (operPtr[-2]) { @@ -585,7 +598,8 @@ int16 Parse_v1::parseExpr(char stopToken, byte *arg_2) { } else if (operStack[brackStart] == 22) { if (decodePtr(values[brackStart]) != _vm->_global->_inter_resStr) { strcpy(_vm->_global->_inter_resStr, decodePtr(values[brackStart])); - values[brackStart] = encodePtr(_vm->_global->_inter_resStr, kResStr); + values[brackStart] = + encodePtr(_vm->_global->_inter_resStr, kResStr); } strcat(_vm->_global->_inter_resStr, decodePtr(valPtr[-1])); } @@ -775,7 +789,7 @@ int16 Parse_v1::parseExpr(char stopToken, byte *arg_2) { break; } // while (stkPos >= 2) - if (operation == 30 || operation == 31) { + if ((operation == 30) || (operation == 31)) { if (operPtr[-1] == 20) { if (valPtr[-1] != 0) operPtr[-1] = 24; @@ -783,19 +797,19 @@ int16 Parse_v1::parseExpr(char stopToken, byte *arg_2) { operPtr[-1] = 23; } - if ((operation == 30 && operPtr[-1] == 24) || - (operation == 31 && operPtr[-1] == 23)) { - if (stkPos > 1 && operPtr[-2] == 9) { + if (((operation == 30) && (operPtr[-1] == 24)) || + ((operation == 31) && (operPtr[-1] == 23))) { + if ((stkPos > 1) && (operPtr[-2] == 9)) { skipExpr(10); operPtr[-2] = operPtr[-1]; stkPos -= 2; operPtr -= 2; valPtr -= 2; - } else { + } else skipExpr(stopToken); - } + operation = _vm->_global->_inter_execPtr[-1]; - if (stkPos > 0 && operPtr[-1] == 11) { + if ((stkPos > 0) && (operPtr[-1] == 11)) { if (operPtr[0] == 23) operPtr[-1] = 24; else @@ -845,7 +859,7 @@ int16 Parse_v1::parseExpr(char stopToken, byte *arg_2) { break; } return 0; - } // operation == stopToken || operation == 30 || operation == 31 || operation == 10 + } // (operation == stopToken) || (operation == 30) || (operation == 31) || (operation == 10) if (operation < 1 || operation > 11) { if (operation < 32 || operation > 37) diff --git a/engines/gob/parse_v2.cpp b/engines/gob/parse_v2.cpp index 132adfa037..b41a34efff 100644 --- a/engines/gob/parse_v2.cpp +++ b/engines/gob/parse_v2.cpp @@ -26,8 +26,8 @@ #include "gob/gob.h" #include "gob/parse.h" -#include "gob/inter.h" #include "gob/global.h" +#include "gob/inter.h" namespace Gob { @@ -84,8 +84,9 @@ int16 Parse_v2::parseVarIndex() { case 24: case 25: temp = _vm->_inter->load16() * 4; - debugC(5, kDebugParser, "oper = %d", (int16)*_vm->_global->_inter_execPtr); - if (operation == 25 && *_vm->_global->_inter_execPtr == 13) { + debugC(5, kDebugParser, "oper = %d", + (int16) *_vm->_global->_inter_execPtr); + if ((operation == 25) && (*_vm->_global->_inter_execPtr == 13)) { _vm->_global->_inter_execPtr++; val = parseValExpr(12); temp += val; @@ -131,7 +132,7 @@ int16 Parse_v2::parseValExpr(unsigned stopToken) { valPtr++; operation = *_vm->_global->_inter_execPtr++; - if (operation >= 16 && operation <= 29) { + if ((operation >= 16) && (operation <= 29)) { *operPtr = 20; switch (operation) { case 16: @@ -140,7 +141,7 @@ int16 Parse_v2::parseValExpr(unsigned stopToken) { case 28: temp = _vm->_inter->load16(); dimCount = *_vm->_global->_inter_execPtr++; - arrDesc = (byte*)_vm->_global->_inter_execPtr; + arrDesc = (byte*) _vm->_global->_inter_execPtr; _vm->_global->_inter_execPtr += dimCount; offset = 0; for (dim = 0; dim < dimCount; dim++) { @@ -156,7 +157,8 @@ int16 Parse_v2::parseValExpr(unsigned stopToken) { else if (operation == 28) { _vm->_global->_inter_execPtr++; temp2 = parseValExpr(12); - *valPtr = READ_VARO_UINT8(temp * 4 + offset * 4 * _vm->_global->_inter_animDataSize + temp2); + *valPtr = READ_VARO_UINT8(temp * 4 + + offset * 4 * _vm->_global->_inter_animDataSize + temp2); } break; @@ -169,8 +171,6 @@ int16 Parse_v2::parseValExpr(unsigned stopToken) { break; case 19: -/* *valPtr = _vm->_inter->load16(); - _vm->_global->_inter_execPtr += 2;*/ *valPtr = (uint16) READ_LE_UINT32(_vm->_global->_inter_execPtr); _vm->_global->_inter_execPtr += 4; break; @@ -203,18 +203,20 @@ int16 Parse_v2::parseValExpr(unsigned stopToken) { parseExpr(10, 0); if (operation == 5) { - _vm->_global->_inter_resVal = _vm->_global->_inter_resVal * _vm->_global->_inter_resVal; + _vm->_global->_inter_resVal = + _vm->_global->_inter_resVal * _vm->_global->_inter_resVal; } else if (operation == 7) { if (_vm->_global->_inter_resVal < 0) _vm->_global->_inter_resVal = -_vm->_global->_inter_resVal; } else if (operation == 10) { - _vm->_global->_inter_resVal = _vm->_util->getRandom(_vm->_global->_inter_resVal); + _vm->_global->_inter_resVal = + _vm->_util->getRandom(_vm->_global->_inter_resVal); } *valPtr = _vm->_global->_inter_resVal; break; } // switch - if (stkPos > 0 && operPtr[-1] == 1) { + if ((stkPos > 0) && (operPtr[-1] == 1)) { stkPos--; operPtr--; valPtr--; @@ -222,7 +224,7 @@ int16 Parse_v2::parseValExpr(unsigned stopToken) { valPtr[0] = -valPtr[1]; } - if (stkPos > 0 && operPtr[-1] > 4 && operPtr[-1] < 9) { + if ((stkPos > 0) && (operPtr[-1] > 4) && (operPtr[-1] < 9)) { stkPos -= 2; operPtr -= 2; valPtr -= 2; @@ -244,11 +246,11 @@ int16 Parse_v2::parseValExpr(unsigned stopToken) { valPtr[0] &= valPtr[2]; break; } - } // if (stkPos > 0 && cmdPtr[-1] > 4 && cmdPtr[-1] < 9) + } // if ((stkPos > 0) && (cmdPtr[-1] > 4) && (cmdPtr[-1] < 9)) continue; } - if (operation >= 1 && operation <= 9) { + if ((operation >= 1) && (operation <= 9)) { *operPtr = operation; continue; } @@ -261,7 +263,7 @@ int16 Parse_v2::parseValExpr(unsigned stopToken) { operPtr[-1] = operPtr[0]; valPtr[-1] = valPtr[0]; - if (stkPos > 1 && operPtr[-2] == 1) { + if ((stkPos > 1) && (operPtr[-2] == 1)) { operPtr[-2] = 20; valPtr[-2] = -valPtr[-1]; @@ -270,7 +272,7 @@ int16 Parse_v2::parseValExpr(unsigned stopToken) { valPtr--; } - if (stkPos > 2 && operPtr[-2] > 4 && operPtr[-2] < 9) { + if ((stkPos > 2) && (operPtr[-2] > 4) && (operPtr[-2] < 9)) { stkPos -= 2; operPtr -= 2; valPtr -= 2; @@ -296,15 +298,14 @@ int16 Parse_v2::parseValExpr(unsigned stopToken) { break; } // operPtr[-2] == 9 - for (brackPos = stkPos - 2; brackPos > 0 && - operStack[brackPos] < 30 - && operStack[brackPos] != 9; brackPos--); + for (brackPos = (stkPos - 2); (brackPos > 0) && + (operStack[brackPos] < 30) && (operStack[brackPos] != 9); + brackPos--); - if (operStack[brackPos] >= 30 - || operStack[brackPos] == 9) + if ((operStack[brackPos] >= 30) || (operStack[brackPos] == 9)) brackPos++; - if (operPtr[-2] < 2 || operPtr[-2] > 8) + if ((operPtr[-2] < 2) || (operPtr[-2] > 8)) break; stkPos -= 2; @@ -337,7 +338,8 @@ int16 Parse_v2::parseValExpr(unsigned stopToken) { if (operation != 10) { if (operation != stopToken) { - debugC(5, kDebugParser, "stoptoken error: %d != %d", operation, stopToken); + debugC(5, kDebugParser, "stoptoken error: %d != %d", + operation, stopToken); } flag = oldflag; return values[0]; @@ -380,7 +382,7 @@ int16 Parse_v2::parseExpr(char stopToken, byte *arg_2) { operPtr++; valPtr++; operation = *_vm->_global->_inter_execPtr++; - if (operation >= 16 && operation <= 29) { + if ((operation >= 16) && (operation <= 29)) { switch (operation) { case 16: case 26: @@ -392,7 +394,7 @@ int16 Parse_v2::parseExpr(char stopToken, byte *arg_2) { *operPtr = operation - 6; temp = _vm->_inter->load16(); dimCount = *_vm->_global->_inter_execPtr++; - arrDescPtr = (byte *)_vm->_global->_inter_execPtr; + arrDescPtr = (byte *) _vm->_global->_inter_execPtr; _vm->_global->_inter_execPtr += dimCount; offset = 0; for (dim = 0; dim < dimCount; dim++) { @@ -406,12 +408,15 @@ int16 Parse_v2::parseExpr(char stopToken, byte *arg_2) { else if (operation == 27) *valPtr = (int16) READ_VARO_UINT16(temp * 2 + offset * 2); else if (operation == 28) { - *valPtr = encodePtr(_vm->_global->_inter_variables + temp * 4 + offset * _vm->_global->_inter_animDataSize * 4, kInterVar); + *valPtr = encodePtr(_vm->_global->_inter_variables + + temp * 4 + offset * _vm->_global->_inter_animDataSize * 4, + kInterVar); if (*_vm->_global->_inter_execPtr == 13) { _vm->_global->_inter_execPtr++; temp2 = parseValExpr(12); *operPtr = 20; - *valPtr = READ_VARO_UINT8(temp * 4 + offset * 4 * _vm->_global->_inter_animDataSize + temp2); + *valPtr = READ_VARO_UINT8(temp * 4 + + offset * 4 * _vm->_global->_inter_animDataSize + temp2); } } break; @@ -445,7 +450,8 @@ int16 Parse_v2::parseExpr(char stopToken, byte *arg_2) { case 22: *operPtr = 22; *valPtr = encodePtr(_vm->_global->_inter_execPtr, kExecPtr); - _vm->_global->_inter_execPtr += strlen(_vm->_global->_inter_execPtr) + 1; + _vm->_global->_inter_execPtr += + strlen(_vm->_global->_inter_execPtr) + 1; break; case 23: @@ -476,7 +482,8 @@ int16 Parse_v2::parseExpr(char stopToken, byte *arg_2) { switch (operation) { case 5: - _vm->_global->_inter_resVal = _vm->_global->_inter_resVal * _vm->_global->_inter_resVal; + _vm->_global->_inter_resVal = + _vm->_global->_inter_resVal * _vm->_global->_inter_resVal; break; case 0: @@ -489,12 +496,13 @@ int16 Parse_v2::parseExpr(char stopToken, byte *arg_2) { prevPrevVal = prevVal; prevVal = curVal; curVal = (curVal + _vm->_global->_inter_resVal / curVal) / 2; - } while (curVal != prevVal && curVal != prevPrevVal); + } while ((curVal != prevVal) && (curVal != prevPrevVal)); _vm->_global->_inter_resVal = curVal; break; case 10: - _vm->_global->_inter_resVal = _vm->_util->getRandom(_vm->_global->_inter_resVal); + _vm->_global->_inter_resVal = + _vm->_util->getRandom(_vm->_global->_inter_resVal); break; case 7: @@ -506,7 +514,7 @@ int16 Parse_v2::parseExpr(char stopToken, byte *arg_2) { *valPtr = _vm->_global->_inter_resVal; break; } - if (stkPos > 0 && (operPtr[-1] == 1 || operPtr[-1] == 11)) { + if ((stkPos > 0) && ((operPtr[-1] == 1) || (operPtr[-1] == 11))) { stkPos--; operPtr--; valPtr--; @@ -568,14 +576,16 @@ int16 Parse_v2::parseExpr(char stopToken, byte *arg_2) { break; } continue; - } // op >= 16 && op <= 29 + } // (op >= 16) && (op <= 29) - if (operation == stopToken || operation == 30 || operation == 31 || operation == 10) { + if ((operation == stopToken) || (operation == 30) || + (operation == 31) || (operation == 10)) { while (stkPos >= 2) { var_1A = 0; - if (operPtr[-2] == 9 && (operation == 10 || operation == stopToken)) { + if ((operPtr[-2] == 9) && + ((operation == 10) || (operation == stopToken))) { operPtr[-2] = operPtr[-1]; - if (operPtr[-2] == 20 || operPtr[-2] == 22) + if ((operPtr[-2] == 20) || (operPtr[-2] == 22)) valPtr[-2] = valPtr[-1]; stkPos--; @@ -634,13 +644,13 @@ int16 Parse_v2::parseExpr(char stopToken, byte *arg_2) { if (operation != stopToken) break; - } // if (operPtr[-2] == 9 && ...) + } // if ((operPtr[-2] == 9) && ...) - for (brackStart = stkPos - 2; brackStart > 0 && - operStack[brackStart] < 30 && - operStack[brackStart] != 9; brackStart--); + for (brackStart = (stkPos - 2); (brackStart > 0) && + (operStack[brackStart] < 30) && (operStack[brackStart] != 9); + brackStart--); - if (operStack[brackStart] >= 30 || operStack[brackStart] == 9) + if ((operStack[brackStart] >= 30) || (operStack[brackStart] == 9)) brackStart++; switch (operPtr[-2]) { @@ -650,7 +660,8 @@ int16 Parse_v2::parseExpr(char stopToken, byte *arg_2) { } else if (operStack[brackStart] == 22) { if (decodePtr(values[brackStart]) != _vm->_global->_inter_resStr) { strcpy(_vm->_global->_inter_resStr, decodePtr(values[brackStart])); - values[brackStart] = encodePtr(_vm->_global->_inter_resStr, kResStr); + values[brackStart] = + encodePtr(_vm->_global->_inter_resStr, kResStr); } strcat(_vm->_global->_inter_resStr, decodePtr(valPtr[-1])); } @@ -823,7 +834,8 @@ int16 Parse_v2::parseExpr(char stopToken, byte *arg_2) { strcpy(_vm->_global->_inter_resStr, decodePtr(valPtr[-3])); valPtr[-3] = encodePtr(_vm->_global->_inter_resStr, kResStr); } - if (scumm_stricmp(_vm->_global->_inter_resStr, decodePtr(valPtr[-1])) != 0) + if (scumm_stricmp(_vm->_global->_inter_resStr, + decodePtr(valPtr[-1])) != 0) operPtr[-3] = 24; } stkPos -= 2; @@ -840,7 +852,7 @@ int16 Parse_v2::parseExpr(char stopToken, byte *arg_2) { break; } // while (stkPos >= 2) - if (operation == 30 || operation == 31) { + if ((operation == 30) || (operation == 31)) { if (operPtr[-1] == 20) { if (valPtr[-1] != 0) operPtr[-1] = 24; @@ -848,9 +860,9 @@ int16 Parse_v2::parseExpr(char stopToken, byte *arg_2) { operPtr[-1] = 23; } - if ((operation == 30 && operPtr[-1] == 24) || - (operation == 31 && operPtr[-1] == 23)) { - if (stkPos > 1 && operPtr[-2] == 9) { + if (((operation == 30) && (operPtr[-1] == 24)) || + ((operation == 31) && (operPtr[-1] == 23))) { + if ((stkPos > 1) && (operPtr[-2] == 9)) { skipExpr(10); operPtr[-2] = operPtr[-1]; stkPos -= 2; @@ -860,7 +872,7 @@ int16 Parse_v2::parseExpr(char stopToken, byte *arg_2) { skipExpr(stopToken); } operation = _vm->_global->_inter_execPtr[-1]; - if (stkPos > 0 && operPtr[-1] == 11) { + if ((stkPos > 0) && (operPtr[-1] == 11)) { if (operPtr[0] == 23) operPtr[-1] = 24; else @@ -910,10 +922,10 @@ int16 Parse_v2::parseExpr(char stopToken, byte *arg_2) { break; } return 0; - } // operation == stopToken || operation == 30 || operation == 31 || operation == 10 + } // (operation == stopToken) || (operation == 30) || (operation == 31) || (operation == 10) - if (operation < 1 || operation > 11) { - if (operation < 32 || operation > 37) + if ((operation < 1) || (operation > 11)) { + if ((operation < 32) || (operation > 37)) continue; if (stkPos > 2) { diff --git a/engines/gob/scenery.cpp b/engines/gob/scenery.cpp index 8b3b12831f..5f9193bbe8 100644 --- a/engines/gob/scenery.cpp +++ b/engines/gob/scenery.cpp @@ -27,27 +27,20 @@ #include "gob/gob.h" #include "gob/scenery.h" -#include "gob/inter.h" -#include "gob/video.h" +#include "gob/global.h" #include "gob/draw.h" #include "gob/game.h" -#include "gob/global.h" -#include "gob/parse.h" +#include "gob/inter.h" namespace Gob { Scenery::Scenery(GobEngine *vm) : _vm(vm) { - int i; - - for (i = 0; i < 20; i++) { + for (int i = 0; i < 20; i++) { _spriteRefs[i] = 0; _spriteResId[i] = 0; } - for (i = 0; i < 70; i++ ) { - _staticPictToSprite[i] = 0; - _animPictToSprite[i] = 0; - } - for (i = 0; i < 10; i++) { + + for (int i = 0; i < 10; i++) { _staticPictCount[i] = 0; _staticResId[i] = 0; _animPictCount[i] = 0; @@ -66,35 +59,63 @@ Scenery::Scenery(GobEngine *vm) : _vm(vm) { _animLeft = 0; _pCaptureCounter = 0; + + for (int i = 0; i < 70; i++ ) { + _staticPictToSprite[i] = 0; + _animPictToSprite[i] = 0; + } +} + +Scenery::~Scenery() { + for (int i = 0; i < 10; i++) { + freeStatic(i); + freeAnim(i); + } +} + +void Scenery::init() { + for (int i = 0; i < 10; i++) { + _animPictCount[i] = 0; + _staticPictCount[i] = -1; + } + + for (int i = 0; i < 20; i++) { + _spriteRefs[i] = 0; + _spriteResId[i] = -1; + } + + _curStaticLayer = -1; + _curStatic = -1; } int16 Scenery::loadStatic(char search) { - int16 tmp; + int16 size; int16 *backsPtr; int16 picsCount; int16 resId; - int16 i; int16 sceneryIndex; - char *extData; - char *dataPtr; + char *extData = 0; + byte *dataPtr; Static *ptr; - int16 offset; int16 pictDescId; int16 width; int16 height; int16 sprResId; int16 sprIndex; - extData = 0; _vm->_inter->evalExpr(&sceneryIndex); - tmp = _vm->_inter->load16(); - backsPtr = (int16 *)_vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += tmp * 2; + + size = _vm->_inter->load16(); + backsPtr = (int16 *) _vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr += size * 2; picsCount = _vm->_inter->load16(); resId = _vm->_inter->load16(); + if (search) { + int i; + for (i = 0; i < 10; i++) { - if (_staticPictCount[i] != -1 && _staticResId[i] == resId) { + if ((_staticPictCount[i] != -1) && (_staticResId[i] == resId)) { _vm->_global->_inter_execPtr += 8 * _staticPictCount[i]; return i; } @@ -109,22 +130,22 @@ int16 Scenery::loadStatic(char search) { if (resId >= 30000) { extData = _vm->_game->loadExtData(resId, 0, 0); - dataPtr = extData; + dataPtr = (byte *) extData; } else - dataPtr = _vm->_game->loadTotResource(resId); + dataPtr = (byte *) _vm->_game->loadTotResource(resId); ptr = &_statics[sceneryIndex]; - ptr->layersCount = (int16)READ_LE_UINT16(dataPtr); + ptr->layersCount = (int16) READ_LE_UINT16(dataPtr); dataPtr += 2; ptr->layers = new StaticLayer[ptr->layersCount]; ptr->pieces = new PieceDesc*[picsCount]; - ptr->piecesFromExt = new int8[picsCount]; + ptr->piecesFromExt = new bool[picsCount]; - for (i = 0; i < ptr->layersCount; i++) { - offset = (int16)READ_LE_UINT16(&((int16 *)dataPtr)[i]); - Common::MemoryReadStream layerData((byte *) (dataPtr + offset), 4294967295U); + for (int i = 0; i < ptr->layersCount; i++) { + int16 offset = READ_LE_UINT16(dataPtr + i * 2); + Common::MemoryReadStream layerData(dataPtr + offset, 4294967295U); ptr->layers[i].planeCount = layerData.readSint16LE(); @@ -138,22 +159,21 @@ int16 Scenery::loadStatic(char search) { ptr->layers[i].planes[j].transp = layerData.readSByte(); } - ptr->layers[i].backResId = (int16)READ_LE_UINT16(backsPtr); + ptr->layers[i].backResId = (int16) READ_LE_UINT16(backsPtr); backsPtr++; } - for (i = 0; i < picsCount; i++) { + for (int i = 0; i < picsCount; i++) { pictDescId = _vm->_inter->load16(); + if (pictDescId >= 30000) { ptr->pieces[i] = - (PieceDesc *) _vm->_game->loadExtData(pictDescId, 0, - 0); - ptr->piecesFromExt[i] = 1; + (PieceDesc *) _vm->_game->loadExtData(pictDescId, 0, 0); + ptr->piecesFromExt[i] = true; } else { ptr->pieces[i] = - (PieceDesc *) - _vm->_game->loadTotResource(pictDescId); - ptr->piecesFromExt[i] = 0; + (PieceDesc *) _vm->_game->loadTotResource(pictDescId); + ptr->piecesFromExt[i] = false; } width = _vm->_inter->load16(); @@ -165,19 +185,16 @@ int16 Scenery::loadStatic(char search) { } if (sprIndex < 20) { - _staticPictToSprite[7 * sceneryIndex + i] = - sprIndex; + _staticPictToSprite[7 * sceneryIndex + i] = sprIndex; _spriteRefs[sprIndex]++; } else { for (sprIndex = 19; _vm->_draw->_spritesArray[sprIndex] != 0; - sprIndex--); + sprIndex--); - _staticPictToSprite[7 * sceneryIndex + i] = - sprIndex; + _staticPictToSprite[7 * sceneryIndex + i] = sprIndex; _spriteRefs[sprIndex] = 1; _spriteResId[sprIndex] = sprResId; - _vm->_draw->_spritesArray[sprIndex] = - _vm->_video->initSurfDesc(_vm->_global->_videoMode, width, height, 2); + _vm->_draw->initSpriteSurf(sprIndex, width, height, 2); _vm->_video->clearSurf(_vm->_draw->_spritesArray[sprIndex]); _vm->_draw->_destSurface = sprIndex; @@ -188,13 +205,13 @@ int16 Scenery::loadStatic(char search) { _vm->_draw->spriteOperation(DRAW_LOADSPRITE); } } - if (extData != 0) - delete[] extData; + + delete[] extData; + return sceneryIndex + 100; } void Scenery::freeStatic(int16 index) { - int16 i; int16 spr; if (index == -1) @@ -203,20 +220,19 @@ void Scenery::freeStatic(int16 index) { if (_staticPictCount[index] == -1) return; - for (i = 0; i < _staticPictCount[index]; i++) { - if (_statics[index].piecesFromExt[i] == 1) + for (int i = 0; i < _staticPictCount[index]; i++) { + if (_statics[index].piecesFromExt[i]) delete[] _statics[index].pieces[i]; spr = _staticPictToSprite[index * 7 + i]; _spriteRefs[spr]--; if (_spriteRefs[spr] == 0) { - _vm->_video->freeSurfDesc(_vm->_draw->_spritesArray[spr]); - _vm->_draw->_spritesArray[spr] = 0; + _vm->_draw->freeSprite(spr); _spriteResId[spr] = -1; } } - for (i = 0; i < _statics[index].layersCount; i++) + for (int i = 0; i < _statics[index].layersCount; i++) delete[] _statics[index].layers[i].planes; delete[] _statics[index].layers; delete[] _statics[index].pieces; @@ -350,22 +366,22 @@ void Scenery::updateStatic(int16 orderFrom) { _vm->_draw->_spriteRight = right - left + 1; _vm->_draw->_spriteBottom = bottom - top + 1; - if (_vm->_draw->_spriteRight <= 0 || _vm->_draw->_spriteBottom <= 0) + if ((_vm->_draw->_spriteRight <= 0) || + (_vm->_draw->_spriteBottom <= 0)) continue; - if (_vm->_draw->_destSpriteX + _vm->_draw->_spriteRight - 1 > + if ((_vm->_draw->_destSpriteX + _vm->_draw->_spriteRight - 1) > _toRedrawRight) _vm->_draw->_spriteRight = _toRedrawRight - _vm->_draw->_destSpriteX + 1; - if (_vm->_draw->_destSpriteY + _vm->_draw->_spriteBottom - 1 > + if ((_vm->_draw->_destSpriteY + _vm->_draw->_spriteBottom - 1) > _toRedrawBottom) _vm->_draw->_spriteBottom = _toRedrawBottom - _vm->_draw->_destSpriteY + 1; _vm->_draw->_sourceSurface = - _staticPictToSprite[_curStatic * 7 + - pictIndex]; + _staticPictToSprite[_curStatic * 7 + pictIndex]; _vm->_draw->_destSurface = 21; _vm->_draw->_transparency = planePtr->transp ? 3 : 0; _vm->_draw->spriteOperation(DRAW_BLITSURF); @@ -381,9 +397,8 @@ int16 Scenery::loadAnim(char search) { int16 sceneryIndex; int16 framesCount; char *extData; - char *dataPtr; + byte *dataPtr; Animation *ptr; - int16 offset; int16 pictDescId; int16 width; int16 height; @@ -398,13 +413,12 @@ int16 Scenery::loadAnim(char search) { if (search) { for (i = 0; i < 10; i++) { - if (_animPictCount[i] != 0 - && _animResId[i] == resId) { + if ((_animPictCount[i] != 0) && (_animResId[i] == resId)) { _vm->_global->_inter_execPtr += 8 * _animPictCount[i]; return i; } - if (_animPictCount[i] == 0 && i < sceneryIndex) + if ((_animPictCount[i] == 0) && (i < sceneryIndex)) sceneryIndex = i; } } @@ -414,9 +428,9 @@ int16 Scenery::loadAnim(char search) { if (resId >= 30000) { extData = _vm->_game->loadExtData(resId, 0, 0); - dataPtr = extData; + dataPtr = (byte *) extData; } else - dataPtr = _vm->_game->loadTotResource(resId); + dataPtr = (byte *) _vm->_game->loadTotResource(resId); ptr = &_animations[sceneryIndex]; @@ -425,11 +439,11 @@ int16 Scenery::loadAnim(char search) { ptr->layers = new AnimLayer[ptr->layersCount]; ptr->pieces = new PieceDesc*[picsCount]; - ptr->piecesFromExt = new int8[picsCount]; + ptr->piecesFromExt = new bool[picsCount]; for (i = 0; i < ptr->layersCount; i++) { - offset = (int16)READ_LE_UINT16(&((int16 *)dataPtr)[i]); - Common::MemoryReadStream layerData((byte *) (dataPtr + offset - 2), 4294967295U); + int16 offset = READ_LE_UINT16(dataPtr + i * 2); + Common::MemoryReadStream layerData(dataPtr + offset - 2, 4294967295U); ptr->layers[i].unknown0 = layerData.readSint16LE(); ptr->layers[i].posX = layerData.readSint16LE(); @@ -442,7 +456,8 @@ int16 Scenery::loadAnim(char search) { layerPos = layerData.pos(); framesCount = 0; layerData.seek(4, SEEK_CUR); - for (j = 0; j < ptr->layers[i].framesCount; j++, framesCount++, layerData.seek(4, SEEK_CUR)) { + for (j = 0; j < ptr->layers[i].framesCount; + j++, framesCount++, layerData.seek(4, SEEK_CUR)) { while (layerData.readByte() == 1) { framesCount++; layerData.seek(4, SEEK_CUR); @@ -464,35 +479,32 @@ int16 Scenery::loadAnim(char search) { pictDescId = _vm->_inter->load16(); if (pictDescId >= 30000) { ptr->pieces[i] = - (PieceDesc *) _vm->_game->loadExtData(pictDescId, 0, - 0); - ptr->piecesFromExt[i] = 1; + (PieceDesc *) _vm->_game->loadExtData(pictDescId, 0, 0); + ptr->piecesFromExt[i] = true; } else { ptr->pieces[i] = - (PieceDesc *) - _vm->_game->loadTotResource(pictDescId); - ptr->piecesFromExt[i] = 0; + (PieceDesc *) _vm->_game->loadTotResource(pictDescId); + ptr->piecesFromExt[i] = false; } width = _vm->_inter->load16(); height = _vm->_inter->load16(); sprResId = _vm->_inter->load16(); - for (sprIndex = 0; sprIndex < 20; sprIndex++) { + for (sprIndex = 0; sprIndex < 20; sprIndex++) if (_spriteResId[sprIndex] == sprResId) break; - } if (sprIndex < 20) { _animPictToSprite[7 * sceneryIndex + i] = sprIndex; _spriteRefs[sprIndex]++; } else { for (sprIndex = 19; _vm->_draw->_spritesArray[sprIndex] != 0; - sprIndex--); + sprIndex--); _animPictToSprite[7 * sceneryIndex + i] = sprIndex; _spriteRefs[sprIndex] = 1; _spriteResId[sprIndex] = sprResId; - _vm->_draw->initBigSprite(sprIndex, width, height, 2); + _vm->_draw->initSpriteSurf(sprIndex, width, height, 2); _vm->_video->clearSurf(_vm->_draw->_spritesArray[sprIndex]); _vm->_draw->_destSurface = sprIndex; @@ -503,68 +515,270 @@ int16 Scenery::loadAnim(char search) { _vm->_draw->spriteOperation(DRAW_LOADSPRITE); } } - if (extData != 0) - delete[] extData; + + delete[] extData; + return sceneryIndex + 100; } -void Scenery::freeAnim(int16 animation) { - int16 i; +void Scenery::freeAnim(int16 index) { int16 spr; - if (animation == -1) - _vm->_inter->evalExpr(&animation); + if (index == -1) + _vm->_inter->evalExpr(&index); - if (_animPictCount[animation] == 0) + if (_animPictCount[index] == 0) return; - for (i = 0; i < _animPictCount[animation]; i++) { - if (_animations[animation].piecesFromExt[i] == 1) - delete[] _animations[animation].pieces[i]; + for (int i = 0; i < _animPictCount[index]; i++) { + if (_animations[index].piecesFromExt[i]) + delete[] _animations[index].pieces[i]; - spr = _animPictToSprite[animation * 7 + i]; + spr = _animPictToSprite[index * 7 + i]; _spriteRefs[spr]--; if (_spriteRefs[spr] == 0) { - _vm->_video->freeSurfDesc(_vm->_draw->_spritesArray[spr]); - - _vm->_draw->_spritesArray[spr] = 0; + _vm->_draw->freeSprite(spr); _spriteResId[spr] = -1; } } - - for (i = 0; i < _animations[animation].layersCount; i++) - delete[] _animations[animation].layers[i].frames; - delete[] _animations[animation].layers; - delete[] _animations[animation].pieces; - delete[] _animations[animation].piecesFromExt; + for (int i = 0; i < _animations[index].layersCount; i++) + delete[] _animations[index].layers[i].frames; + delete[] _animations[index].layers; + delete[] _animations[index].pieces; + delete[] _animations[index].piecesFromExt; - _animPictCount[animation] = 0; + _animPictCount[index] = 0; } -void Scenery::interStoreParams(void) { +// flags & 1 - do capture all area animation is occupying +// flags & 4 == 0 - calculate animation final size +// flags & 2 != 0 - don't check with "toRedraw"'s +// flags & 4 != 0 - checkk view toRedraw +void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags, + int16 drawDeltaX, int16 drawDeltaY, char doDraw) { AnimLayer *layerPtr; - int16 animation; - int16 layer; - int16 var; + PieceDesc **pictPtr; + AnimFramePiece *framePtr; + + uint16 pieceIndex; + uint16 pictIndex; + + int16 left; + int16 right; + int16 top; + int16 bottom; + + byte highX; + byte highY; + + int16 i; + int16 transp; + + int16 destX; + int16 destY; - warning("interStoreParams: Storing..."); + if ((_animPictCount[animation] == 0) || (layer < 0)) + return; + if (layer >= _animations[animation].layersCount) + return; - _vm->_inter->evalExpr(&animation); - _vm->_inter->evalExpr(&layer); layerPtr = &_animations[animation].layers[layer]; - var = _vm->_parse->parseVarIndex(); - WRITE_VAR_OFFSET(var, layerPtr->animDeltaX); + if (frame >= layerPtr->framesCount) + return; + + if (flags & 1) // Do capture + { + updateAnim(layer, frame, animation, 0, drawDeltaX, drawDeltaY, 0); + + if (_toRedrawLeft == -12345) + return; + + _vm->_game->capturePush(_toRedrawLeft, _toRedrawTop, + _toRedrawRight - _toRedrawLeft + 1, + _toRedrawBottom - _toRedrawTop + 1); + + *_pCaptureCounter = *_pCaptureCounter + 1; + } + + pictPtr = _animations[animation].pieces; + framePtr = layerPtr->frames; + + for (i = 0; i < frame; i++, framePtr++) + while (framePtr->notFinal == 1) + framePtr++; + + if (flags & 4) { + _toRedrawLeft = MAX(_toRedrawLeft, _vm->_mult->_animLeft); + _toRedrawTop = MAX(_toRedrawTop, _vm->_mult->_animTop); + _toRedrawRight = MIN(_toRedrawRight, + (int16)(_vm->_mult->_animLeft + _vm->_mult->_animWidth - 1)); + _toRedrawBottom = MIN(_toRedrawBottom, + (int16)(_vm->_mult->_animTop + _vm->_mult->_animHeight - 1)); + } else + _toRedrawLeft = -12345; + + transp = layerPtr->transp ? 3 : 0; + + framePtr--; + do { + framePtr++; + + pieceIndex = framePtr->pieceIndex; + pictIndex = framePtr->pictIndex; + + destX = framePtr->destX; + destY = framePtr->destY; + + highX = pictIndex & 0xC0; + highY = pictIndex & 0x30; + highX >>= 6; + highY >>= 4; + if (destX >= 0) + destX += ((uint16)highX) << 7; + else + destX -= ((uint16)highX) << 7; + + if (destY >= 0) + destY += ((uint16)highY) << 7; + else + destY -= ((uint16)highY) << 7; + + if (drawDeltaX == 1000) + destX += layerPtr->posX; + else + destX += drawDeltaX; + + if (drawDeltaY == 1000) + destY += layerPtr->posY; + else + destY += drawDeltaY; + + pictIndex = (pictIndex & 15) - 1; + + left = FROM_LE_16(pictPtr[pictIndex][pieceIndex].left); + right = FROM_LE_16(pictPtr[pictIndex][pieceIndex].right); + top = FROM_LE_16(pictPtr[pictIndex][pieceIndex].top); + bottom = FROM_LE_16(pictPtr[pictIndex][pieceIndex].bottom); + + if (flags & 2) { + if (destX < _vm->_mult->_animLeft) { + left += _vm->_mult->_animLeft - destX; + destX = _vm->_mult->_animLeft; + } + + if ((left <= right) && ((destX + right - left) >= + (_vm->_mult->_animLeft + _vm->_mult->_animWidth))) + right -= (destX + right - left) - + (_vm->_mult->_animLeft + _vm->_mult->_animWidth) + 1; + + if (destY < _vm->_mult->_animTop) { + top += _vm->_mult->_animTop - destY; + destY = _vm->_mult->_animTop; + } + + if ((top <= bottom) && ((destY + bottom - top) >= + (_vm->_mult->_animTop + _vm->_mult->_animHeight))) + bottom -= (destY + bottom - top) - + (_vm->_mult->_animTop + _vm->_mult->_animHeight) + 1; + + } else if (flags & 4) { + if (destX < _toRedrawLeft) { + left += _toRedrawLeft - destX; + destX = _toRedrawLeft; + } + + if ((left <= right) && ((destX + right - left) > _toRedrawRight)) + right -= destX + right - left - _toRedrawRight; + + if (destY < _toRedrawTop) { + top += _toRedrawTop - destY; + destY = _toRedrawTop; + } + + if ((top <= bottom) && ((destY + bottom - top) > _toRedrawBottom)) + bottom -= destY + bottom - top - _toRedrawBottom; + } + + if ((left > right) || (top > bottom)) + continue; - var = _vm->_parse->parseVarIndex(); - WRITE_VAR_OFFSET(var, layerPtr->animDeltaY); + if (doDraw) { + _vm->_draw->_sourceSurface = + _animPictToSprite[animation * 7 + pictIndex]; + _vm->_draw->_destSurface = 21; + + _vm->_draw->_spriteLeft = left; + _vm->_draw->_spriteTop = top; + _vm->_draw->_spriteRight = right - left + 1; + _vm->_draw->_spriteBottom = bottom - top + 1; + _vm->_draw->_destSpriteX = destX; + _vm->_draw->_destSpriteY = destY; + _vm->_draw->_transparency = transp; + _vm->_draw->spriteOperation(DRAW_BLITSURF); + } + + if (!(flags & 4)) { + if (_toRedrawLeft == -12345) { + _toRedrawLeft = destX; + _animLeft = destX; + _toRedrawTop = destY; + _animTop = destY; + _toRedrawRight = destX + right - left; + _animRight = destX + right - left; + _toRedrawBottom = destY + bottom - top; + _animBottom = destY + bottom - top; + } else { + _toRedrawLeft = MIN(_toRedrawLeft, destX); + _toRedrawTop = MIN(_toRedrawTop, destY); + _toRedrawRight = + MAX(_toRedrawRight, (int16)(destX + right - left)); + _toRedrawBottom = + MAX(_toRedrawBottom, (int16)(destY + bottom - top)); + } + } + + } while (framePtr->notFinal == 1); +} + +void Scenery::writeAnimLayerInfo(uint16 index, uint16 layer, + int16 varDX, int16 varDY, int16 varUnk0, int16 varFrames) { + + assert(index < 10); + assert(layer < _animations[index].layersCount); + + AnimLayer &animLayer = _animations[index].layers[layer]; + WRITE_VAR_OFFSET(varDX, animLayer.animDeltaX); + WRITE_VAR_OFFSET(varDY, animLayer.animDeltaY); + WRITE_VAR_OFFSET(varUnk0, animLayer.unknown0); + WRITE_VAR_OFFSET(varFrames, animLayer.framesCount); +} + +int16 Scenery::getStaticLayersCount(uint16 index) { + assert(index < 10); + + return _statics[index].layersCount; +} + +int16 Scenery::getAnimLayersCount(uint16 index) { + assert(index < 10); + + return _animations[index].layersCount; +} + +Scenery::StaticLayer *Scenery::getStaticLayer(uint16 index, uint16 layer) { + assert(index < 10); + assert(layer < _statics[index].layersCount); + + return &_statics[index].layers[layer]; +} - var = _vm->_parse->parseVarIndex(); - WRITE_VAR_OFFSET(var, layerPtr->unknown0); +Scenery::AnimLayer *Scenery::getAnimLayer(uint16 index, uint16 layer) { + assert(index < 10); + assert(layer < _animations[index].layersCount); - var = _vm->_parse->parseVarIndex(); - WRITE_VAR_OFFSET(var, layerPtr->framesCount); + return &_animations[index].layers[layer]; } -} // End of namespace Gob +} // End of namespace Gob diff --git a/engines/gob/scenery.h b/engines/gob/scenery.h index a5769bb37a..4b3b2f18b6 100644 --- a/engines/gob/scenery.h +++ b/engines/gob/scenery.h @@ -20,6 +20,7 @@ * $Id$ * */ + #ifndef GOB_SCENERY_H #define GOB_SCENERY_H @@ -79,7 +80,7 @@ public: int16 layersCount; StaticLayer *layers; PieceDesc **pieces; - int8 *piecesFromExt; + bool *piecesFromExt; Static() : layersCount(0), layers(0), pieces(0), piecesFromExt(0) {} }; @@ -88,26 +89,11 @@ public: int16 layersCount; AnimLayer *layers; PieceDesc **pieces; - int8 *piecesFromExt; + bool *piecesFromExt; Animation() : layersCount(0), layers(0), pieces(0), piecesFromExt(0) {} }; - // Global variables - - char _spriteRefs[20]; - int16 _spriteResId[20]; - - char _staticPictToSprite[70]; - int16 _staticPictCount[10]; - Static _statics[10]; - int16 _staticResId[10]; - - char _animPictToSprite[70]; - int16 _animPictCount[10]; - Animation _animations[10]; - int16 _animResId[10]; - int16 _curStatic; int16 _curStaticLayer; @@ -123,31 +109,49 @@ public: int16 *_pCaptureCounter; - // Functions - + void init(); int16 loadStatic(char search); void freeStatic(int16 index); void renderStatic(int16 scenery, int16 layer); void updateStatic(int16 orderFrom); - void freeAnim(int16 animation); - void interStoreParams(void); + void freeAnim(int16 index); + void updateAnim(int16 layer, int16 frame, int16 animation, + int16 flags, int16 drawDeltaX, int16 drawDeltaY, char doDraw); + void writeAnimLayerInfo(uint16 index, uint16 layer, + int16 varDX, int16 varDY, int16 varUnk0, int16 varFrames); + int16 getStaticLayersCount(uint16 index); + int16 getAnimLayersCount(uint16 index); + StaticLayer *getStaticLayer(uint16 index, uint16 layer); + AnimLayer *getAnimLayer(uint16 index, uint16 layer); + virtual int16 loadAnim(char search); - virtual void updateAnim(int16 layer, int16 frame, int16 animation, - int16 flags, int16 drawDeltaX, int16 drawDeltaY, char doDraw) = 0; Scenery(GobEngine *vm); - virtual ~Scenery() {}; + virtual ~Scenery(); protected: + char _spriteRefs[20]; + int16 _spriteResId[20]; + + int16 _staticPictCount[10]; + int16 _staticResId[10]; + + int16 _animPictCount[10]; + int16 _animResId[10]; + + char _staticPictToSprite[70]; + char _animPictToSprite[70]; + + Static _statics[10]; + Animation _animations[10]; + GobEngine *_vm; }; class Scenery_v1 : public Scenery { public: virtual int16 loadAnim(char search); - virtual void updateAnim(int16 layer, int16 frame, int16 animation, - int16 flags, int16 drawDeltaX, int16 drawDeltaY, char doDraw); Scenery_v1(GobEngine *vm); virtual ~Scenery_v1() {}; @@ -156,13 +160,11 @@ public: class Scenery_v2 : public Scenery_v1 { public: virtual int16 loadAnim(char search); - virtual void updateAnim(int16 layer, int16 frame, int16 animation, - int16 flags, int16 drawDeltaX, int16 drawDeltaY, char doDraw); Scenery_v2(GobEngine *vm); virtual ~Scenery_v2() {}; }; -} // End of namespace Gob +} // End of namespace Gob -#endif /* __SCENERY_H */ +#endif // GOB_SCENERY_H diff --git a/engines/gob/scenery_v1.cpp b/engines/gob/scenery_v1.cpp index 5912d96100..c88ad8d0ec 100644 --- a/engines/gob/scenery_v1.cpp +++ b/engines/gob/scenery_v1.cpp @@ -26,9 +26,6 @@ #include "gob/gob.h" #include "gob/scenery.h" -#include "gob/anim.h" -#include "gob/draw.h" -#include "gob/game.h" #include "gob/util.h" #include "gob/cdrom.h" @@ -48,211 +45,4 @@ int16 Scenery_v1::loadAnim(char search) { return Scenery::loadAnim(search); } -// flags & 1 - do capture all area animation is occupying -// flags & 4 == 0 - calculate animation final size -// flags & 2 != 0 - don't check with "toRedraw"'s -// flags & 4 != 0 - checkk view toRedraw -void Scenery_v1::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags, - int16 drawDeltaX, int16 drawDeltaY, char doDraw) { - AnimLayer *layerPtr; - PieceDesc **pictPtr; - - uint16 pieceIndex; - uint16 pictIndex; - - int16 curFrame; - - int16 left; - int16 right; - int16 top; - int16 bottom; - - byte highX; - byte highY; - - int16 i; - int16 transp; - - int16 destX; - int16 destY; - - if (layer >= _animations[animation].layersCount) - return; - - layerPtr = &_animations[animation].layers[layer]; - - if (frame >= layerPtr->framesCount) - return; - - if (flags & 1) // Do capture - { - updateAnim(layer, frame, animation, 0, drawDeltaX, - drawDeltaY, 0); - - if (_toRedrawLeft == -12345) // Some magic number? - return; - - _vm->_game->capturePush(_toRedrawLeft, _toRedrawTop, - _toRedrawRight - _toRedrawLeft + 1, - _toRedrawBottom - _toRedrawTop + 1); - - *_pCaptureCounter = *_pCaptureCounter + 1; - } - pictPtr = _animations[animation].pieces; - curFrame = 0; - - for (i = 0; i < frame; i++, curFrame++) { - while (layerPtr->frames[curFrame].notFinal == 1) - curFrame++; - } - - if ((flags & 4) == 0) { - _toRedrawLeft = -12345; - } else { - _toRedrawLeft = - MAX(_toRedrawLeft, _vm->_anim->_areaLeft); - _toRedrawTop = - MAX(_toRedrawTop, _vm->_anim->_areaTop); - _toRedrawRight = - MIN(_toRedrawRight, - (int16)(_vm->_anim->_areaLeft + _vm->_anim->_areaWidth - 1)); - _toRedrawBottom = - MIN(_toRedrawBottom, - (int16)(_vm->_anim->_areaTop + _vm->_anim->_areaHeight - 1)); - } - - transp = layerPtr->transp ? 3 : 0; - - curFrame--; - do { - curFrame++; - - pieceIndex = layerPtr->frames[curFrame].pieceIndex; - pictIndex = layerPtr->frames[curFrame].pictIndex; - - destX = layerPtr->frames[curFrame].destX; - destY = layerPtr->frames[curFrame].destY; - - highX = pictIndex & 0xc0; - highY = pictIndex & 0x30; - highX >>= 6; - highY >>= 4; - if (destX >= 0) - destX += ((uint16)highX) << 7; - else - destX -= ((uint16)highX) << 7; - - if (destY >= 0) - destY += ((uint16)highY) << 7; - else - destY -= ((uint16)highY) << 7; - - if (drawDeltaX == 1000) - destX += layerPtr->posX; - else - destX += drawDeltaX; - - if (drawDeltaY == 1000) - destY += layerPtr->posY; - else - destY += drawDeltaY; - - pictIndex = (pictIndex & 15) - 1; - - left = READ_LE_UINT16(&pictPtr[pictIndex][pieceIndex].left); - right = READ_LE_UINT16(&pictPtr[pictIndex][pieceIndex].right); - top = READ_LE_UINT16(&pictPtr[pictIndex][pieceIndex].top); - bottom = READ_LE_UINT16(&pictPtr[pictIndex][pieceIndex].bottom); - - if (flags & 2) { - if (destX < _vm->_anim->_areaLeft) { - left += _vm->_anim->_areaLeft - destX; - destX = _vm->_anim->_areaLeft; - } - - if (left <= right - && destX + right - left >= - _vm->_anim->_areaLeft + _vm->_anim->_areaWidth) - right -= - (destX + right - left) - - (_vm->_anim->_areaLeft + _vm->_anim->_areaWidth) + - 1; - - if (destY < _vm->_anim->_areaTop) { - top += _vm->_anim->_areaTop - destY; - destY = _vm->_anim->_areaTop; - } - - if (top <= bottom - && destY + bottom - top >= - _vm->_anim->_areaTop + _vm->_anim->_areaHeight) - bottom -= - (destY + bottom - top) - - (_vm->_anim->_areaTop + _vm->_anim->_areaHeight) + - 1; - - } else if (flags & 4) { - if (destX < _toRedrawLeft) { - left += _toRedrawLeft - destX; - destX = _toRedrawLeft; - } - - if (left <= right - && destX + right - left > _toRedrawRight) - right -= - destX + right - left - _toRedrawRight; - - if (destY < _toRedrawTop) { - top += _toRedrawTop - destY; - destY = _toRedrawTop; - } - - if (top <= bottom - && destY + bottom - top > _toRedrawBottom) - bottom -= - destY + bottom - top - _toRedrawBottom; - } - - if (left > right || top > bottom) - continue; - - if (doDraw) { - _vm->_draw->_sourceSurface = - _animPictToSprite[animation * 7 + pictIndex]; - _vm->_draw->_destSurface = 21; - - _vm->_draw->_spriteLeft = left; - _vm->_draw->_spriteTop = top; - _vm->_draw->_spriteRight = right - left + 1; - _vm->_draw->_spriteBottom = bottom - top + 1; - _vm->_draw->_destSpriteX = destX; - _vm->_draw->_destSpriteY = destY; - _vm->_draw->_transparency = transp; - _vm->_draw->spriteOperation(DRAW_BLITSURF); - } - - if ((flags & 4) == 0) { - if (_toRedrawLeft == -12345) { - _toRedrawLeft = destX; - _animLeft = destX; - _toRedrawTop = destY; - _animTop = destY; - _toRedrawRight = destX + right - left; - _toRedrawBottom = destY + bottom - top; - } else { - _toRedrawLeft = - MIN(_toRedrawLeft, destX); - _toRedrawTop = - MIN(_toRedrawTop, destY); - _toRedrawRight = - MAX(_toRedrawRight, - (int16)(destX + right - left)); - _toRedrawBottom = - MAX(_toRedrawBottom, - (int16)(destY + bottom - top)); - } - } - } while (layerPtr->frames[curFrame].notFinal == 1); -} - } // End of namespace Gob diff --git a/engines/gob/scenery_v2.cpp b/engines/gob/scenery_v2.cpp index 5bac467501..d8067f3347 100644 --- a/engines/gob/scenery_v2.cpp +++ b/engines/gob/scenery_v2.cpp @@ -26,9 +26,6 @@ #include "gob/gob.h" #include "gob/scenery.h" -#include "gob/anim.h" -#include "gob/draw.h" -#include "gob/game.h" namespace Gob { @@ -39,217 +36,4 @@ int16 Scenery_v2::loadAnim(char search) { return Scenery::loadAnim(search); } -// flags & 1 - do capture all area animation is occupying -// flags & 4 == 0 - calculate animation final size -// flags & 2 != 0 - don't check with "toRedraw"'s -// flags & 4 != 0 - checkk view toRedraw -void Scenery_v2::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags, - int16 drawDeltaX, int16 drawDeltaY, char doDraw) { - AnimLayer *layerPtr; - PieceDesc **pictPtr; - AnimFramePiece *framePtr; - - uint16 pieceIndex; - uint16 pictIndex; - - int16 left; - int16 right; - int16 top; - int16 bottom; - - byte highX; - byte highY; - - int16 i; - int16 transp; - - int16 destX; - int16 destY; - - if ((_animPictCount[animation] == 0) || (layer < 0)) - return; - if (layer >= _animations[animation].layersCount) - return; - - layerPtr = &_animations[animation].layers[layer]; - - if (frame >= layerPtr->framesCount) - return; - - if (flags & 1) // Do capture - { - updateAnim(layer, frame, animation, 0, drawDeltaX, - drawDeltaY, 0); - - if (_toRedrawLeft == -12345) // Some magic number? - return; - - _vm->_game->capturePush(_toRedrawLeft, _toRedrawTop, - _toRedrawRight - _toRedrawLeft + 1, - _toRedrawBottom - _toRedrawTop + 1); - - *_pCaptureCounter = *_pCaptureCounter + 1; - } - - pictPtr = _animations[animation].pieces; - framePtr = layerPtr->frames; - - for (i = 0; i < frame; i++, framePtr++) { - while (framePtr->notFinal == 1) - framePtr++; - } - - if ((flags & 4) == 0) { - _toRedrawLeft = -12345; - } else { - _toRedrawLeft = - MAX(_toRedrawLeft, _vm->_anim->_areaLeft); - _toRedrawTop = - MAX(_toRedrawTop, _vm->_anim->_areaTop); - _toRedrawRight = - MIN(_toRedrawRight, - (int16)(_vm->_anim->_areaLeft + _vm->_anim->_areaWidth - 1)); - _toRedrawBottom = - MIN(_toRedrawBottom, - (int16)(_vm->_anim->_areaTop + _vm->_anim->_areaHeight - 1)); - } - - transp = layerPtr->transp ? 3 : 0; - - framePtr--; - do { - framePtr++; - - pieceIndex = framePtr->pieceIndex; - pictIndex = framePtr->pictIndex; - - destX = framePtr->destX; - destY = framePtr->destY; - - highX = pictIndex & 0xc0; - highY = pictIndex & 0x30; - highX >>= 6; - highY >>= 4; - if (destX >= 0) - destX += ((uint16)highX) << 7; - else - destX -= ((uint16)highX) << 7; - - if (destY >= 0) - destY += ((uint16)highY) << 7; - else - destY -= ((uint16)highY) << 7; - - if (drawDeltaX == 1000) - destX += layerPtr->posX; - else - destX += drawDeltaX; - - if (drawDeltaY == 1000) - destY += layerPtr->posY; - else - destY += drawDeltaY; - - pictIndex = (pictIndex & 15) - 1; - - left = FROM_LE_16(pictPtr[pictIndex][pieceIndex].left); - right = FROM_LE_16(pictPtr[pictIndex][pieceIndex].right); - top = FROM_LE_16(pictPtr[pictIndex][pieceIndex].top); - bottom = FROM_LE_16(pictPtr[pictIndex][pieceIndex].bottom); - - if (flags & 2) { - if (destX < _vm->_anim->_areaLeft) { - left += _vm->_anim->_areaLeft - destX; - destX = _vm->_anim->_areaLeft; - } - - if (left <= right - && destX + right - left >= - _vm->_anim->_areaLeft + _vm->_anim->_areaWidth) - right -= - (destX + right - left) - - (_vm->_anim->_areaLeft + _vm->_anim->_areaWidth) + - 1; - - if (destY < _vm->_anim->_areaTop) { - top += _vm->_anim->_areaTop - destY; - destY = _vm->_anim->_areaTop; - } - - if (top <= bottom - && destY + bottom - top >= - _vm->_anim->_areaTop + _vm->_anim->_areaHeight) - bottom -= - (destY + bottom - top) - - (_vm->_anim->_areaTop + _vm->_anim->_areaHeight) + - 1; - - } else if (flags & 4) { - if (destX < _toRedrawLeft) { - left += _toRedrawLeft - destX; - destX = _toRedrawLeft; - } - - if (left <= right - && destX + right - left > _toRedrawRight) - right -= - destX + right - left - _toRedrawRight; - - if (destY < _toRedrawTop) { - top += _toRedrawTop - destY; - destY = _toRedrawTop; - } - - if (top <= bottom - && destY + bottom - top > _toRedrawBottom) - bottom -= - destY + bottom - top - _toRedrawBottom; - } - - // --- - - if (left > right || top > bottom) - continue; - - if (doDraw) { - _vm->_draw->_sourceSurface = - _animPictToSprite[animation * 7 + pictIndex]; - _vm->_draw->_destSurface = 21; - - _vm->_draw->_spriteLeft = left; - _vm->_draw->_spriteTop = top; - _vm->_draw->_spriteRight = right - left + 1; - _vm->_draw->_spriteBottom = bottom - top + 1; - _vm->_draw->_destSpriteX = destX; - _vm->_draw->_destSpriteY = destY; - _vm->_draw->_transparency = transp; - _vm->_draw->spriteOperation(DRAW_DRAWLETTER); - } - - if ((flags & 4) == 0) { - if (_toRedrawLeft == -12345) { - _toRedrawLeft = destX; - _animLeft = destX; - _toRedrawTop = destY; - _animTop = destY; - _toRedrawRight = destX + right - left; - _animRight = destX + right - left; - _toRedrawBottom = destY + bottom - top; - _animBottom = destY + bottom - top; - } else { - _toRedrawLeft = - MIN(_toRedrawLeft, destX); - _toRedrawTop = - MIN(_toRedrawTop, destY); - _toRedrawRight = - MAX(_toRedrawRight, - (int16)(destX + right - left)); - _toRedrawBottom = - MAX(_toRedrawBottom, - (int16)(destY + bottom - top)); - } - } - } while (framePtr->notFinal == 1); -} - } // End of namespace Gob diff --git a/engines/gob/sound.cpp b/engines/gob/sound.cpp index 0832702a94..336f3b2c1c 100644 --- a/engines/gob/sound.cpp +++ b/engines/gob/sound.cpp @@ -21,14 +21,67 @@ * */ +#include "common/stdafx.h" +#include "common/endian.h" + #include "gob/gob.h" -#include "gob/global.h" #include "gob/sound.h" -#include "gob/game.h" +#include "gob/global.h" #include "gob/util.h" +#include "gob/dataio.h" +#include "gob/game.h" namespace Gob { +void SoundDesc::load(SoundType type, SoundSource src, + byte *data, uint32 dSize) { + + free(); + + _source = src; + switch (type) { + case SOUND_ADL: + loadADL(data, dSize); + break; + case SOUND_SND: + loadSND(data, dSize); + break; + } +} + +void SoundDesc::free() { + if (_source != SOUND_TOT) + delete[] _data; + _data = _dataPtr = 0; + _id = 0; +} + +void SoundDesc::flip() { + if ((_type == SOUND_SND) && _data && _dataPtr) { + _frequency = -_frequency; + for (uint32 i = 0; i < _size; i++) + _dataPtr[i] ^= 0x80; + } +} + +void SoundDesc::loadSND(byte *data, uint32 dSize) { + assert(dSize > 6); + + _type = SOUND_SND; + _data = data; + _dataPtr = data + 6; + _frequency = MAX((int16) READ_BE_UINT16(data + 4), (int16) 4700); + _flag = data[0] ? (data[0] & 0x7F) : 8; + data[0] = 0; + _size = MIN(READ_BE_UINT32(data), dSize - 6); +} + +void SoundDesc::loadADL(byte *data, uint32 dSize) { + _type = SOUND_ADL; + _data = _dataPtr = data; + _size = dSize; +} + Snd::SquareWaveStream::SquareWaveStream() { _rate = 44100; _beepForever = false; @@ -119,7 +172,6 @@ Snd::Snd(GobEngine *vm) : _vm(vm) { _curFadeSamples = 0; _compositionSamples = 0; - _compositionSampleTypes = 0; _compositionSampleCount = 0; _compositionPos = -1; @@ -144,7 +196,7 @@ void Snd::speakerOn(int16 frequency, int32 length) { _speakerStartTimeKey = _vm->_util->getTimeKey(); } -void Snd::speakerOff(void) { +void Snd::speakerOff() { _speakerStream.stop(_vm->_util->getTimeKey() - _speakerStartTimeKey); } @@ -152,13 +204,17 @@ void Snd::speakerOnUpdate(uint32 milis) { _speakerStream.update(milis); } -void Snd::stopSound(int16 fadeLength) { +void Snd::stopSound(int16 fadeLength, SoundDesc *sndDesc) { Common::StackLock slock(_mutex); + if (sndDesc && (sndDesc != _curSoundDesc)) + return; + if (fadeLength <= 0) { _data = 0; _end = true; _playingSound = 0; + _curSoundDesc = 0; return; } @@ -182,21 +238,24 @@ void Snd::waitEndPlay(bool interruptible, bool stopComp) { stopSound(0); } -void Snd::stopComposition(void) { +void Snd::stopComposition() { if (_compositionPos != -1) { stopSound(0); _compositionPos = -1; } } -void Snd::nextCompositionPos(void) { +void Snd::nextCompositionPos() { int8 slot; - while ((++_compositionPos < 50) && ((slot = _composition[_compositionPos]) != -1)) { - if ((slot >= 0) && (slot < _compositionSampleCount) && - (_compositionSamples[slot] != 0) && !(_compositionSampleTypes[slot] & 8)) { - setSample(_compositionSamples[slot], 1, 0, 0); - return; + while ((++_compositionPos < 50) && + ((slot = _composition[_compositionPos]) != -1)) { + if ((slot >= 0) && (slot < _compositionSampleCount)) { + SoundDesc &sample = _compositionSamples[slot]; + if (!sample.empty() && (sample.getType() == SOUND_SND)) { + setSample(sample, 1, 0, 0); + return; + } } if (_compositionPos == 49) _compositionPos = -1; @@ -204,15 +263,14 @@ void Snd::nextCompositionPos(void) { _compositionPos = -1; } -void Snd::playComposition(int16 *composition, int16 freqVal, SoundDesc **sndDescs, - int8 *sndTypes, int8 sndCount) { +void Snd::playComposition(int16 *composition, int16 freqVal, + SoundDesc *sndDescs, int8 sndCount) { int i; waitEndPlay(); stopComposition(); _compositionSamples = sndDescs ? sndDescs : _vm->_game->_soundSamples; - _compositionSampleTypes = sndTypes ? sndTypes : _vm->_game->_soundTypes; _compositionSampleCount = sndCount; i = -1; @@ -221,39 +279,22 @@ void Snd::playComposition(int16 *composition, int16 freqVal, SoundDesc **sndDesc _composition[i] = composition[i]; } while ((i < 50) && (composition[i] != -1)); + _compositionPos = -1; nextCompositionPos(); } -Snd::SoundDesc *Snd::loadSoundData(const char *path) { - Snd::SoundDesc *sndDesc; - - sndDesc = new Snd::SoundDesc; - sndDesc->size = _vm->_dataio->getDataSize(path); - sndDesc->data = _vm->_dataio->getData(path); - - return sndDesc; -} - -void Snd::freeSoundDesc(Snd::SoundDesc *sndDesc, bool freedata) { - if (sndDesc == _curSoundDesc) - stopSound(0); +void Snd::setSample(SoundDesc &sndDesc, int16 repCount, int16 frequency, + int16 fadeLength) { - if (freedata) { - delete[] sndDesc->data; - } - delete sndDesc; -} - -void Snd::setSample(Snd::SoundDesc *sndDesc, int16 repCount, int16 frequency, int16 fadeLength) { if (frequency <= 0) - frequency = sndDesc->frequency; + frequency = sndDesc._frequency; - _curSoundDesc = sndDesc; - sndDesc->repCount = repCount - 1; - sndDesc->frequency = frequency; + _curSoundDesc = &sndDesc; + sndDesc._repCount = repCount - 1; + sndDesc._frequency = frequency; - _data = (int8 *) sndDesc->data; - _length = sndDesc->size; + _data = (int8 *) sndDesc.getData(); + _length = sndDesc.size(); _freq = frequency; _ratio = ((double) _freq) / _rate; _offset = 0.0; @@ -278,7 +319,27 @@ void Snd::setSample(Snd::SoundDesc *sndDesc, int16 repCount, int16 frequency, in } } -void Snd::playSample(Snd::SoundDesc *sndDesc, int16 repCount, int16 frequency, int16 fadeLength) { +bool Snd::loadSample(SoundDesc &sndDesc, const char *fileName) { + byte *data; + uint32 size; + + data = (byte *) _vm->_dataIO->getData(fileName); + if (!data) + return false; + + size = _vm->_dataIO->getDataSize(fileName); + sndDesc.load(SOUND_SND, SOUND_FILE, data, size); + + return true; +} + +void Snd::freeSample(SoundDesc &sndDesc) { + stopSound(0, &sndDesc); + sndDesc.free(); +} + +void Snd::playSample(SoundDesc &sndDesc, int16 repCount, int16 frequency, + int16 fadeLength) { Common::StackLock slock(_mutex); if (!_end) @@ -287,7 +348,7 @@ void Snd::playSample(Snd::SoundDesc *sndDesc, int16 repCount, int16 frequency, i setSample(sndDesc, repCount, frequency, fadeLength); } -void Snd::checkEndSample(void) { +void Snd::checkEndSample() { if (_compositionPos != -1) nextCompositionPos(); else if ((_repCount == -1) || (--_repCount > 0)) { @@ -328,6 +389,7 @@ int Snd::readBuffer(int16 *buffer, const int numSamples) { _end = true; _playingSound = 0; _compositionPos = -1; + _curSoundDesc = 0; } else { _fadeVol = 255.0; _fade = false; diff --git a/engines/gob/sound.h b/engines/gob/sound.h index 0a574ef06c..2981e222bd 100644 --- a/engines/gob/sound.h +++ b/engines/gob/sound.h @@ -20,48 +20,91 @@ * $Id$ * */ + #ifndef GOB_SOUND_H #define GOB_SOUND_H +#include "common/mutex.h" #include "sound/audiostream.h" #include "sound/mixer.h" namespace Gob { -class Snd : public Audio::AudioStream { +enum SoundType { + SOUND_SND, + SOUND_ADL +}; + +enum SoundSource { + SOUND_FILE, + SOUND_TOT, + SOUND_EXT +}; + +class SoundDesc { public: - struct SoundDesc { - Audio::SoundHandle handle; - char *data; - uint32 size; - int16 repCount; - int16 timerTicks; - int16 inClocks; - int16 frequency; - int16 flag; - SoundDesc() : data(0), size(0), repCount(0), timerTicks(0), - inClocks(0), frequency(0), flag(0) {} - }; + int16 _repCount; + int16 _frequency; + int16 _flag; + int16 _id; + + byte *getData() { return _dataPtr; } + uint32 size() { return _size; } + bool empty() { return !_dataPtr; } + bool isId(int16 id) { return _dataPtr && _id == id; }; + SoundType getType() { return _type; } + + void load(SoundType type, SoundSource src, byte *data, uint32 dSize); + void free(); + void flip(); + + // Which fade out length to use when the fade starts half-way through? + int16 calcFadeOutLength(int16 frequency) { + return (10 * (_size / 2)) / frequency; + } + uint32 calcLength(int16 repCount, int16 frequency, bool fade) { + uint32 fadeSize = fade ? _size / 2 : 0; + return ((_size * repCount - fadeSize) * 1000) / frequency; + } + + SoundDesc() : _data(0), _dataPtr(0), _size(0), _type(SOUND_SND), + _source(SOUND_FILE), _repCount(0), _frequency(0), + _flag(0), _id(0) {} + ~SoundDesc() { free(); } + +private: + byte *_data; + byte *_dataPtr; + uint32 _size; + SoundType _type; + SoundSource _source; + + void loadSND(byte *data, uint32 dSize); + void loadADL(byte *data, uint32 dSize); +}; + +class Snd : public Audio::AudioStream { +public: char _playingSound; Snd(GobEngine *vm); ~Snd(); void speakerOn(int16 frequency, int32 length); - void speakerOff(void); + void speakerOff(); void speakerOnUpdate(uint32 milis); - SoundDesc *loadSoundData(const char *path); - void stopSound(int16 fadeLength); - void playSample(SoundDesc *sndDesc, int16 repCount, int16 frequency, int16 fadeLength = 0); - void playComposition(int16 *composition, int16 freqVal, SoundDesc **sndDescs = 0, - int8 *sndTypes = 0, int8 sndCount = 60); - void stopComposition(void); - void waitEndPlay(bool interruptible = false, bool stopComp = true); + void stopSound(int16 fadeLength, SoundDesc *sndDesc = 0); - // This deletes sndDesc and stops playing the sample. - // If freedata is set, it also delete[]s the sample data. - void freeSoundDesc(SoundDesc *sndDesc, bool freedata=true); + bool loadSample(SoundDesc &sndDesc, const char *fileName); + void freeSample(SoundDesc &sndDesc); + void playSample(SoundDesc &sndDesc, int16 repCount, + int16 frequency, int16 fadeLength = 0); + + void playComposition(int16 *composition, int16 freqVal, + SoundDesc *sndDescs = 0, int8 sndCount = 60); + void stopComposition(); + void waitEndPlay(bool interruptible = false, bool stopComp = true); int readBuffer(int16 *buffer, const int numSamples); bool isStereo() const { return false; } @@ -70,7 +113,7 @@ public: int getRate() const { return _rate; } protected: - // TODO: This is a very primitive square wave generator. The only thing is + // TODO: This is a very primitive square wave generator. The only thing it // has in common with the PC speaker is that it sounds terrible. // Note: The SCUMM code has a PC speaker implementations; maybe it could be // refactored to be reusable by all engines. And DosBox also has code @@ -107,8 +150,7 @@ protected: Audio::SoundHandle *_activeHandle; Audio::SoundHandle _compositionHandle; - SoundDesc **_compositionSamples; - int8 *_compositionSampleTypes; + SoundDesc *_compositionSamples; int8 _compositionSampleCount; int16 _composition[50]; int8 _compositionPos; @@ -138,11 +180,12 @@ protected: GobEngine *_vm; - void setSample(Snd::SoundDesc *sndDesc, int16 repCount, int16 frequency, int16 fadeLength); - void checkEndSample(void); - void nextCompositionPos(void); + void setSample(SoundDesc &sndDesc, int16 repCount, + int16 frequency, int16 fadeLength); + void checkEndSample(); + void nextCompositionPos(); }; -} // End of namespace Gob +} // End of namespace Gob -#endif +#endif // GOB_SOUND_H diff --git a/engines/gob/timer.cpp b/engines/gob/timer.cpp deleted file mode 100644 index 19de498992..0000000000 --- a/engines/gob/timer.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004 Ivan Dubrov - * Copyright (C) 2004-2006 The ScummVM project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ -#include "gob/gob.h" -#include "gob/global.h" -#include "gob/sound.h" -#include "gob/timer.h" - -namespace Gob { - -void GTimer::enableTimer() { - debugC(4, kDebugGameFlow, "STUB: GTimer::enableTimer()"); -} - -void GTimer::disableTimer() { - debugC(4, kDebugGameFlow, "STUB: GTimer::disableTimer()"); -} -} diff --git a/engines/gob/timer.h b/engines/gob/timer.h deleted file mode 100644 index d47d20b376..0000000000 --- a/engines/gob/timer.h +++ /dev/null @@ -1,43 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004 Ivan Dubrov - * Copyright (C) 2004-2006 The ScummVM project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ -#ifndef GOB_TIMER_H -#define GOB_TIMER_H - -namespace Gob { - -class GTimer { -public: - typedef void (* TickHandler) (void); - - void enableTimer(void); - void disableTimer(void); - void setHandler(void); - void restoreHandler(void); - void addTicks(int16 ticks); - void setTickHandler(TickHandler handler); - int32 getTicks(void); -}; - -} // End of namespace Gob - -#endif diff --git a/engines/gob/util.cpp b/engines/gob/util.cpp index fc85cf3e73..1b0e01727d 100644 --- a/engines/gob/util.cpp +++ b/engines/gob/util.cpp @@ -20,15 +20,19 @@ * $Id$ * */ + +#include "common/stdafx.h" +#include "common/events.h" + #include "gob/gob.h" -#include "gob/global.h" -#include "gob/timer.h" #include "gob/util.h" +#include "gob/global.h" +#include "gob/dataio.h" #include "gob/draw.h" #include "gob/game.h" -#include "gob/inter.h" - -#include "common/events.h" +#include "gob/imd.h" +#include "gob/sound.h" +#include "gob/video.h" namespace Gob { @@ -40,6 +44,80 @@ Util::Util(GobEngine *vm) : _vm(vm) { _keyBufferTail = 0; } +uint32 Util::getTimeKey(void) { + return g_system->getMillis(); +} + +int16 Util::getRandom(int16 max) { + return _vm->_rnd.getRandomNumber(max - 1); +} + +void Util::beep(int16 freq) { + if (_vm->_global->_soundFlags == 0) + return; + + _vm->_snd->speakerOn(freq, 50); +} + +void Util::delay(uint16 msecs) { + g_system->delayMillis(msecs); +} + +void Util::longDelay(uint16 msecs) { + uint32 time = g_system->getMillis() + msecs; + do { + _vm->_video->waitRetrace(_vm->_global->_videoMode); + processInput(); + delay(15); + } while (!_vm->_quitRequested && (g_system->getMillis() < time)); +} + +void Util::initInput(void) { + _mouseButtons = 0; + _keyBufferHead = _keyBufferTail = 0; +} + +void Util::processInput() { + Common::Event event; + Common::EventManager *eventMan = g_system->getEventManager(); + + while (eventMan->pollEvent(event)) { + switch (event.type) { + case Common::EVENT_LBUTTONDOWN: + _mouseButtons |= 1; + break; + case Common::EVENT_RBUTTONDOWN: + _mouseButtons |= 2; + break; + case Common::EVENT_LBUTTONUP: + _mouseButtons &= ~1; + break; + case Common::EVENT_RBUTTONUP: + _mouseButtons &= ~2; + break; + case Common::EVENT_KEYDOWN: + addKeyToBuffer(event.kbd.keycode); + break; + case Common::EVENT_KEYUP: + break; + case Common::EVENT_QUIT: + _vm->_quitRequested = true; + break; + default: + break; + } + } +} + +void Util::clearKeyBuf(void) { + processInput(); + _keyBufferHead = _keyBufferTail = 0; +} + +bool Util::keyBufferEmpty() { + return (_keyBufferHead == _keyBufferTail); +} + void Util::addKeyToBuffer(int16 key) { if ((_keyBufferHead + 1) % KEYBUFSIZE == _keyBufferTail) { warning("key buffer overflow"); @@ -50,10 +128,6 @@ void Util::addKeyToBuffer(int16 key) { _keyBufferHead = (_keyBufferHead + 1) % KEYBUFSIZE; } -bool Util::keyBufferEmpty() { - return (_keyBufferHead == _keyBufferTail); -} - bool Util::getKeyFromBuffer(int16& key) { if (_keyBufferHead == _keyBufferTail) return false; @@ -63,50 +137,37 @@ bool Util::getKeyFromBuffer(int16& key) { return true; } - -void Util::initInput(void) { - _mouseButtons = 0; - _keyBufferHead = _keyBufferTail = 0; -} - -void Util::waitKey(void) { - // FIXME: wrong function name? This functions clears the keyboard buffer. - processInput(); - _keyBufferHead = _keyBufferTail = 0; -} - int16 Util::translateKey(int16 key) { - struct keyS { + static struct keyS { int16 from; int16 to; } keys[] = { - {8, 0x0e08}, // Backspace - {32, 0x3920}, // Space - {13, 0x1C0D}, // Enter - {27, 0x011b}, // ESC - {127, 0x5300}, // Del - {273, 0x4800}, // Up arrow - {274, 0x5000}, // Down arrow - {275, 0x4D00}, // Right arrow - {276, 0x4B00}, // Left arrow - {282, 0x3b00}, // F1 - {283, 0x3c00}, // F2 - {284, 0x3d00}, // F3 - {285, 0x3E00}, // F4 - {286, 0x011b}, // F5 - {287, 0x4000}, // F6 - {288, 0x4100}, // F7 - {289, 0x4200}, // F8 - {290, 0x4300}, // F9 - {291, 0x4400} // F10 + {8, 0x0E08}, // Backspace + {32, 0x3920}, // Space + {13, 0x1C0D}, // Enter + {27, 0x011B}, // ESC + {127, 0x5300}, // Del + {273, 0x4800}, // Up arrow + {274, 0x5000}, // Down arrow + {275, 0x4D00}, // Right arrow + {276, 0x4B00}, // Left arrow + {282, 0x3B00}, // F1 + {283, 0x3C00}, // F2 + {284, 0x3D00}, // F3 + {285, 0x3E00}, // F4 + {286, 0x011B}, // F5 + {287, 0x4000}, // F6 + {288, 0x4100}, // F7 + {289, 0x4200}, // F8 + {290, 0x4300}, // F9 + {291, 0x4400} // F10 }; - int i; - for (i = 0; i < ARRAYSIZE(keys); i++) + for (int i = 0; i < ARRAYSIZE(keys); i++) if (key == keys[i].from) return keys[i].to; - if (key < 32 || key >= 128) + if ((key < 32) || (key >= 128)) return 0; return key; @@ -133,41 +194,6 @@ int16 Util::checkKey(void) { return translateKey(key); } -int16 Util::getRandom(int16 max) { - return _vm->_rnd.getRandomNumber(max - 1); -} - -void Util::processInput() { - Common::Event event; - Common::EventManager *eventMan = g_system->getEventManager(); - while (eventMan->pollEvent(event)) { - switch (event.type) { - case Common::EVENT_LBUTTONDOWN: - _mouseButtons |= 1; - break; - case Common::EVENT_RBUTTONDOWN: - _mouseButtons |= 2; - break; - case Common::EVENT_LBUTTONUP: - _mouseButtons &= ~1; - break; - case Common::EVENT_RBUTTONUP: - _mouseButtons &= ~2; - break; - case Common::EVENT_KEYDOWN: - addKeyToBuffer(event.kbd.keycode); - break; - case Common::EVENT_KEYUP: - break; - case Common::EVENT_QUIT: - _vm->_quitRequested = true; - break; - default: - break; - } - } -} - void Util::getMouseState(int16 *pX, int16 *pY, int16 *pButtons) { Common::Point mouse = g_system->getEventManager()->getMousePos(); *pX = mouse.x; @@ -181,52 +207,60 @@ void Util::setMousePos(int16 x, int16 y) { g_system->warpMouse(x, y); } -void Util::longDelay(uint16 msecs) { - uint32 time = g_system->getMillis() + msecs; +void Util::waitMouseUp(void) { do { - _vm->_video->waitRetrace(_vm->_global->_videoMode); processInput(); - delay(15); - } while (!_vm->_quitRequested && (g_system->getMillis() < time)); -} - -void Util::delay(uint16 msecs) { - g_system->delayMillis(msecs); -} - -void Util::beep(int16 freq) { - if (_vm->_global->_soundFlags == 0) - return; - - _vm->_snd->speakerOn(freq, 50); + if (_mouseButtons != 0) + delay(10); + } while (_mouseButtons != 0); } -uint32 Util::getTimeKey(void) { - return g_system->getMillis(); -} +void Util::waitMouseDown(void) { + int16 x; + int16 y; + int16 buttons; -void Util::waitMouseUp(void) { do { processInput(); - if (_mouseButtons != 0) delay(10); - } while (_mouseButtons != 0); + getMouseState(&x, &y, &buttons); + if (buttons == 0) + delay(10); + } while (buttons == 0); } -void Util::waitMouseDown(void) { +void Util::waitMouseRelease(char drawMouse) { + int16 buttons; + int16 mouseX; + int16 mouseY; + do { - processInput(); - if (_mouseButtons == 0) delay(10); - } while (_mouseButtons == 0); + _vm->_game->checkKeys(&mouseX, &mouseY, &buttons, drawMouse); + if (drawMouse != 0) + _vm->_draw->animateCursor(2); + delay(10); + } while (buttons != 0); } -/* NOT IMPLEMENTED */ -int16 Util::calcDelayTime() { - return 0; +void Util::forceMouseUp(void) { + _vm->_game->_mouseButtons = 0; + _mouseButtons = 0; } -/* NOT IMPLEMENTED */ -void Util::checkJoystick() { - _vm->_global->_useJoystick = 0; +void Util::clearPalette(void) { + int16 i; + byte colors[768]; + + _vm->validateVideoMode(_vm->_global->_videoMode); + + if (_vm->_global->_setAllPalette) { + for (i = 0; i < 768; i++) + colors[i] = 0; + g_system->setPalette(colors, 0, 256); + return; + } + + for (i = 0; i < 16; i++) + _vm->_video->setPalElem(i, 0, 0, 0, 0, _vm->_global->_videoMode); } void Util::setFrameRate(int16 rate) { @@ -235,7 +269,7 @@ void Util::setFrameRate(int16 rate) { _vm->_global->_frameWaitTime = 1000 / rate; _vm->_global->_startFrameTime = getTimeKey(); - _vm->_game->_dword_2F2B6 = 0; + _vm->_imdPlayer->_frameDelay = 0; } void Util::waitEndFrame() { @@ -244,42 +278,43 @@ void Util::waitEndFrame() { _vm->_video->waitRetrace(_vm->_global->_videoMode); time = getTimeKey() - _vm->_global->_startFrameTime; - if (time > 1000 || time < 0) { + if ((time > 1000) || (time < 0)) { _vm->_global->_startFrameTime = getTimeKey(); - _vm->_game->_dword_2F2B6 = 0; + _vm->_imdPlayer->_frameDelay = 0; return; } + if (_vm->_global->_frameWaitTime - time > 0) { - _vm->_game->_dword_2F2B6 = 0; - delay(_vm->_global->_frameWaitTime - _vm->_game->_dword_2F2B6 - time); + _vm->_imdPlayer->_frameDelay = 0; + delay(_vm->_global->_frameWaitTime - _vm->_imdPlayer->_frameDelay - time); } - _vm->_global->_startFrameTime = getTimeKey(); - _vm->_game->_dword_2F2B6 = time - _vm->_global->_frameWaitTime; -} -int16 joy_getState() { - return 0; + _vm->_global->_startFrameTime = getTimeKey(); + _vm->_imdPlayer->_frameDelay = time - _vm->_global->_frameWaitTime; } -int16 joy_calibrate() { - return 0; +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); } Video::FontDesc *Util::loadFont(const char *path) { Video::FontDesc *fontDesc = new Video::FontDesc; char *data; - if (fontDesc == 0) + if (!fontDesc) return 0; - data = _vm->_dataio->getData(path); - if (data == 0) { + data = _vm->_dataIO->getData(path); + if (!data) { delete fontDesc; return 0; } fontDesc->dataPtr = data + 4; - fontDesc->itemWidth = data[0] & 0x7f; + fontDesc->itemWidth = data[0] & 0x7F; fontDesc->itemHeight = data[1]; fontDesc->startItem = data[2]; fontDesc->endItem = data[3]; @@ -289,85 +324,90 @@ Video::FontDesc *Util::loadFont(const char *path) { fontDesc->bitWidth = fontDesc->itemWidth; if (data[0] & 0x80) - fontDesc->extraData = - data + 4 + fontDesc->itemSize * (fontDesc->endItem - - fontDesc->startItem + 1); + fontDesc->extraData = data + 4 + fontDesc->itemSize * + (fontDesc->endItem - fontDesc->startItem + 1); else fontDesc->extraData = 0; + return fontDesc; } -void Util::freeFont(Video::FontDesc * fontDesc) { +void Util::freeFont(Video::FontDesc *fontDesc) { delete[] (fontDesc->dataPtr - 4); delete fontDesc; } -void Util::clearPalette(void) { - int16 i; - byte colors[768]; - - if ((_vm->_global->_videoMode != 0x13) && (_vm->_global->_videoMode != 0x14)) - error("clearPalette: Video mode 0x%x is not supported!", - _vm->_global->_videoMode); - - if (_vm->_global->_setAllPalette) { - for (i = 0; i < 768; i++) - colors[i] = 0; - g_system->setPalette(colors, 0, 256); - - return; - } - - for (i = 0; i < 16; i++) - _vm->_video->setPalElem(i, 0, 0, 0, 0, _vm->_global->_videoMode); -} - void Util::insertStr(const char *str1, char *str2, int16 pos) { - int16 len1; - int16 i; - int16 from; - - i = strlen(str2); - len1 = strlen(str1); - if (pos < i) - from = pos; - else - from = i; + int len1 = strlen(str1); + int len2 = strlen(str2); + int from = MIN((int) pos, len2); - for (; i >= from; i--) + for (int i = len2; i >= from; i--) str2[len1 + i] = str2[i]; - - for (i = 0; i < len1; i++) + for (int i = 0; i < len1; i++) str2[i + from] = str1[i]; } void Util::cutFromStr(char *str, int16 from, int16 cutlen) { - int16 len; - int16 i; + int len = strlen(str); - //log_write("cutFromStr: str = %s, ", str); - len = strlen(str); if (from >= len) return; - if (from + cutlen > len) { + if ((from + cutlen) > len) { str[from] = 0; - //log_write("res = %s\n", str); return; } - i = from; + int i = from; do { str[i] = str[i + cutlen]; i++; } while (str[i] != 0); - //log_write("res = %s\n", str); } -void Util::listInsertFront(List * list, void *data) { +static const char trStr1[] = + " ' + - :0123456789: <=> abcdefghijklmnopqrstuvwxyz " + "abcdefghijklmnopqrstuvwxyz "; +static const char trStr2[] = + " ueaaaaceeeiii ooouu aioun" + " "; +static const char trStr3[] = " "; + +void Util::prepareStr(char *str) { + char *start, *end; + char buf[300]; + + strcpy(buf, trStr1); + strcat(buf, trStr2); + strcat(buf, trStr3); + + for (size_t i = 0; i < strlen(str); i++) + str[i] = buf[str[i] - 32]; + + while (str[0] == ' ') + cutFromStr(str, 0, 1); + + while ((strlen(str) > 0) && (str[strlen(str) - 1] == ' ')) + cutFromStr(str, strlen(str) - 1, 1); + + start = strchr(str, ' '); + + while (start) { + if (start[1] == ' ') { + cutFromStr(str, start - str, 1); + continue; + } + + end = strchr(start + 1, ' '); + start = end ? end + 1 : 0; + } +} + +void Util::listInsertFront(List *list, void *data) { ListNode *node; node = new ListNode; - if (list->pHead != 0) { + if (list->pHead) { node->pData = data; node->pNext = list->pHead; node->pPrev = 0; @@ -382,7 +422,7 @@ void Util::listInsertFront(List * list, void *data) { } } -void Util::listInsertBack(List * list, void *data) { +void Util::listInsertBack(List *list, void *data) { ListNode *node; if (list->pHead != 0) { @@ -397,12 +437,11 @@ void Util::listInsertBack(List * list, void *data) { node->pNext = 0; list->pTail->pNext = node; list->pTail = node; - } else { + } else listInsertFront(list, data); - } } -void Util::listDropFront(List * list) { +void Util::listDropFront(List *list) { if (list->pHead->pNext == 0) { delete list->pHead; list->pHead = 0; @@ -414,77 +453,16 @@ void Util::listDropFront(List * list) { } } -void Util::deleteList(List * list) { - while (list->pHead != 0) { +void Util::deleteList(List *list) { + while (list->pHead) listDropFront(list); - } delete list; } -static const char trStr1[] = - " ' + - :0123456789: <=> abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz "; -static const char trStr2[] = - " ueaaaaceeeiii ooouu aioun "; -static const char trStr3[] = " "; - -void Util::prepareStr(char *str) { - uint16 i; - char *start, *end; - char buf[300]; - - strcpy(buf, trStr1); - strcat(buf, trStr2); - strcat(buf, trStr3); - - for (i = 0; i < strlen(str); i++) - str[i] = buf[str[i] - 32]; - - while (str[0] == ' ') - cutFromStr(str, 0, 1); - - while (strlen(str) > 0 && str[strlen(str) - 1] == ' ') - cutFromStr(str, strlen(str) - 1, 1); - - start = strchr(str, ' '); - - while (start != 0) { - if (*(start+1) == ' ') { - cutFromStr(str, start - str, 1); - continue; - } - - end = strchr(start + 1, ' '); - if (end != 0) - start = end + 1; - else - start = 0; - } -} - -void Util::waitMouseRelease(char drawMouse) { - int16 buttons; - int16 mouseX; - int16 mouseY; - - do { - _vm->_game->checkKeys(&mouseX, &mouseY, &buttons, drawMouse); - if (drawMouse != 0) - _vm->_draw->animateCursor(2); - delay(10); - } while (buttons != 0); -} - -void Util::forceMouseUp(void) { - _vm->_game->_mouseButtons = 0; - _mouseButtons = 0; -} - -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); +/* NOT IMPLEMENTED */ +void Util::checkJoystick() { + _vm->_global->_useJoystick = 0; } } // End of namespace Gob diff --git a/engines/gob/util.h b/engines/gob/util.h index 40e9f6bb51..946da23665 100644 --- a/engines/gob/util.h +++ b/engines/gob/util.h @@ -20,11 +20,11 @@ * $Id$ * */ + #ifndef GOB_UTIL_H #define GOB_UTIL_H #include "gob/video.h" -#include "gob/global.h" namespace Gob { @@ -46,58 +46,60 @@ public: List() : pHead(0), pTail(0) {} }; + uint32 getTimeKey(void); + int16 getRandom(int16 max); + void beep(int16 freq); + + void delay(uint16 msecs); + void longDelay(uint16 msecs); + void initInput(void); void processInput(void); - void waitKey(void); + void clearKeyBuf(void); int16 getKey(void); int16 checkKey(void); - int16 getRandom(int16 max); + void getMouseState(int16 *pX, int16 *pY, int16 *pButtons); void setMousePos(int16 x, int16 y); - void longDelay(uint16 msecs); - void delay(uint16 msecs); - void beep(int16 freq); - uint32 getTimeKey(void); void waitMouseUp(void); void waitMouseDown(void); + void waitMouseRelease(char drawMouse); + void forceMouseUp(void); void clearPalette(void); - - void asm_setPaletteBlock(char *tmpPalBuffer, int16 start, int16 end); - - void vid_waitRetrace(int16 mode); + void setFrameRate(int16 rate); + void waitEndFrame(); + void setScrollOffset(int16 x = -1, int16 y = -1); Video::FontDesc *loadFont(const char *path); - void freeFont(Video::FontDesc * fontDesc); + void freeFont(Video::FontDesc *fontDesc); + static void insertStr(const char *str1, char *str2, int16 pos); static void cutFromStr(char *str, int16 from, int16 cutlen); - void waitEndFrame(); - void setFrameRate(int16 rate); - - static void listInsertBack(List * list, void *data); - static void listInsertFront(List * list, void *data); - static void listDropFront(List * list); - static void deleteList(List * list); static void prepareStr(char *str); - void waitMouseRelease(char drawMouse); - void forceMouseUp(void); - void setScrollOffset(int16 x = -1, int16 y = -1); + + static void listInsertFront(List *list, void *data); + static void listInsertBack(List *list, void *data); + static void listDropFront(List *list); + static void deleteList(List *list); Util(GobEngine *vm); protected: int16 _mouseButtons; - int16 _keyBuffer[KEYBUFSIZE], _keyBufferHead, _keyBufferTail; + int16 _keyBuffer[KEYBUFSIZE]; + int16 _keyBufferHead; + int16 _keyBufferTail; + GobEngine *_vm; - void addKeyToBuffer(int16 key); bool keyBufferEmpty(); + void addKeyToBuffer(int16 key); bool getKeyFromBuffer(int16& key); int16 translateKey(int16 key); - int16 calcDelayTime(); void checkJoystick(); }; -} // End of namespace Gob +} // End of namespace Gob -#endif +#endif // GOB_UTIL_H diff --git a/engines/gob/video.cpp b/engines/gob/video.cpp index bbe909e189..67798d81d8 100644 --- a/engines/gob/video.cpp +++ b/engines/gob/video.cpp @@ -20,12 +20,15 @@ * $Id$ * */ + #include "common/stdafx.h" #include "common/endian.h" +#include "graphics/cursorman.h" #include "gob/gob.h" -#include "gob/global.h" #include "gob/video.h" +#include "gob/global.h" +#include "gob/util.h" #include "gob/dataio.h" #include "gob/draw.h" @@ -33,9 +36,54 @@ namespace Gob { -/* NOT IMPLEMENTED */ +SurfaceDesc::SurfaceDesc(int16 vidMode, int16 width, int16 height, + byte *vidMem) : _width(width), _height(height) { + + if (vidMem) { + _vidMode = vidMode; + _ownVidMem = false; + _vidMem = vidMem; + } else { + _vidMode = vidMode; + _ownVidMem = true; + _vidMem = new byte[width * height]; + assert(_vidMem); + memset(_vidMem, 0, width * height); + } +} + +void SurfaceDesc::setVidMem(byte *vidMem) { + assert(vidMem); + + if (hasOwnVidMem()) + delete[] _vidMem; + + _ownVidMem = false; + _vidMem = vidMem; +} + +void SurfaceDesc::resize(int16 width, int16 height) { + if (hasOwnVidMem()) + delete[] _vidMem; + + _width = width; + _height = height; + _ownVidMem = true; + _vidMem = new byte[width * height]; + assert(_vidMem); + memset(_vidMem, 0, width * height); +} + +void SurfaceDesc::swap(SurfaceDesc &surf) { + SWAP(_width, surf._width); + SWAP(_height, surf._height); + SWAP(_vidMode, surf._vidMode); + SWAP(_ownVidMem, surf._ownVidMem); + SWAP(_vidMem, surf._vidMem); +} Video::Video(GobEngine *vm) : _vm(vm) { + _doRangeClamp = false; _videoDriver = 0; _surfWidth = 320; _surfHeight = 200; @@ -47,91 +95,173 @@ char Video::initDriver(int16 vidMode) { if (_videoDriver) return 1; - warning("STUB: Video::initDriver"); - - // FIXME: Finish all this stuff :) _videoDriver = new VGAVideoDriver(); - return 1; } void Video::freeDriver() { delete _videoDriver; - warning("STUB: Video::freeDriver"); } -int32 Video::getRectSize(int16 width, int16 height, int16 flag, int16 mode) { - int32 size; - - if (((mode & 0x7f) != 0x13) && ((mode & 0x7f) != 0x14)) - warning - ("Video::getRectSize: Video mode %d is not fully supported!", - mode & 0x7f); - switch (mode & 0x7f) { - case 5: - case 7: - size = ((int32)((width + 3) / 4)) * height * (flag + 1); - break; - case 0x13: - size = (int32)width *height; - break; - case 0x14: - case 0x15: - case 0x16: - size = ((int32)((width + 3) / 4)) * height * 4; - break; - default: - size = ((int32)((width + 7) / 8)) * height * (flag + 4); - break; +void Video::initPrimary(int16 mode) { + if ((mode != 3) && (mode != -1)) + _vm->validateVideoMode(mode); + _vm->validateVideoMode(_vm->_global->_videoMode); + + if (mode == -1) + mode = 3; + _vm->_global->_oldMode = mode; + + if (mode != 3) + Video::initDriver(mode); + + if (mode != 3) { + initSurfDesc(mode, _surfWidth, _surfHeight, PRIMARY_SURFACE); + + if (!_vm->_global->_dontSetPalette) + Video::setFullPalette(_vm->_global->_pPaletteDesc); + } +} + +SurfaceDesc *Video::initSurfDesc(int16 vidMode, int16 width, int16 height, + int16 flags) { + SurfaceDesc *descPtr = 0; + + if (flags & PRIMARY_SURFACE) + assert((width == _surfWidth) && (height == _surfHeight)); + + _vm->validateVideoMode(vidMode); + + if (flags & PRIMARY_SURFACE) { + _vm->_global->_primaryWidth = width; + _vm->_global->_mouseMaxCol = width; + _vm->_global->_primaryHeight = height; + _vm->_global->_mouseMaxRow = height; + + descPtr = _vm->_global->_primarySurfDesc; + descPtr->resize(width, height); + descPtr->_vidMode = vidMode; + } else { + assert(!(flags & DISABLE_SPR_ALLOC)); + + if (!(flags & SCUMMVM_CURSOR)) + width = (width + 7) & 0xFFF8; + + descPtr = new SurfaceDesc(vidMode, width, height); + } + return descPtr; +} + +void Video::waitRetrace(bool mouse) { + uint32 time; + + 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))); } - return size; } -void Video::freeSurfDesc(SurfaceDesc * surfDesc) { - if ((surfDesc == 0) || (surfDesc == _vm->_draw->_frontSurface)) +void Video::putPixel(int16 x, int16 y, int16 color, SurfaceDesc *dest) { + if ((x >= dest->getWidth()) || (x < 0) || + (y >= dest->getHeight()) || (y < 0)) return; - delete[] surfDesc->vidPtr; - if (surfDesc != _vm->_global->_pPrimarySurfDesc) { - _vm->_global->_sprAllocated--; - delete surfDesc; + _videoDriver->putPixel(x, y, color, dest); +} + +void Video::fillRect(SurfaceDesc *dest, int16 left, int16 top, int16 right, + int16 bottom, int16 color) { + + if (_doRangeClamp) { + if (left > right) + SWAP(left, right); + if (top > bottom) + SWAP(top, bottom); + + if ((left >= dest->getWidth()) || (right < 0) || + (top >= dest->getHeight()) || (bottom < 0)) + return; + + left = CLIP(left, (int16) 0, (int16) (dest->getWidth() - 1)); + top = CLIP(top, (int16) 0, (int16) (dest->getHeight() - 1)); + right = CLIP(right, (int16) 0, (int16) (dest->getWidth() - 1)); + bottom = CLIP(bottom, (int16) 0, (int16) (dest->getHeight() - 1)); } + + _videoDriver->fillRect(dest, left, top, right, bottom, color); } -int16 Video::clampValue(int16 val, int16 max) { - if (val >= max) - val = max - 1; +void Video::drawLine(SurfaceDesc *dest, int16 x0, int16 y0, int16 x1, + int16 y1, int16 color) { + + if ((x0 == x1) || (y0 == y1)) + Video::fillRect(dest, x0, y0, x1, y1, color); + else + _videoDriver->drawLine(dest, x0, y0, x1, y1, color); +} - if (val < 0) - val = 0; +/* + * The original's version of the Bresenham Algorithm was a bit "unclean" + * and produced strange edges at 45°, 135°, 225° and 315°, so using the + * version found in the Wikipedia article about the + * "Bresenham's line algorithm" instead + */ +void Video::drawCircle(SurfaceDesc *dest, int16 x0, int16 y0, + int16 radius, int16 color) { + int16 f = 1 - radius; + int16 ddFx = 0; + int16 ddFy = -2 * radius; + int16 x = 0; + int16 y = radius; + + putPixel(x0, y0 + radius, color, dest); + putPixel(x0, y0 - radius, color, dest); + putPixel(x0 + radius, y0, color, dest); + putPixel(x0 - radius, y0, color, dest); + + while (x < y) { + if (f >= 0) { + y--; + ddFy += 2; + f += ddFy; + } + x++; + ddFx += 2; + f += ddFx + 1; + putPixel(x0 + x, y0 + y, color, dest); + putPixel(x0 - x, y0 + y, color, dest); + putPixel(x0 + x, y0 - y, color, dest); + putPixel(x0 - x, y0 - y, color, dest); + putPixel(x0 + y, y0 + x, color, dest); + putPixel(x0 - y, y0 + x, color, dest); + putPixel(x0 + y, y0 - x, color, dest); + putPixel(x0 - y, y0 - x, color, dest); + } +} - return val; +void Video::clearSurf(SurfaceDesc *dest) { + Video::fillRect(dest, 0, 0, dest->getWidth() - 1, dest->getHeight() - 1, 0); } void Video::drawSprite(SurfaceDesc *source, SurfaceDesc *dest, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp) { - int16 temp; int16 destRight; int16 destBottom; - if (_vm->_global->_doRangeClamp) { - if (left > right) { - temp = left; - left = right; - right = temp; - } - if (top > bottom) { - temp = top; - top = bottom; - bottom = temp; - } - if (right < 0) - return; - if (bottom < 0) - return; - if (left >= source->width) - return; - if (top >= source->height) + if (_doRangeClamp) { + if (left > right) + SWAP(left, right); + if (top > bottom) + SWAP(top, bottom); + + if ((left >= source->getWidth()) || (right < 0) || + (top >= source->getHeight()) || (bottom < 0)) return; if (left < 0) { @@ -142,12 +272,12 @@ void Video::drawSprite(SurfaceDesc *source, SurfaceDesc *dest, y -= top; top = 0; } - right = Video::clampValue(right, source->width); - bottom = Video::clampValue(bottom, source->height); - if (right - left >= source->width) - right = left + source->width - 1; - if (bottom - top >= source->height) - bottom = top + source->height - 1; + right = CLIP(right, (int16) 0, (int16) (source->getWidth() - 1)); + bottom = CLIP(bottom, (int16) 0, (int16) (source->getHeight() - 1)); + if (right - left >= source->getWidth()) + right = left + source->getWidth() - 1; + if (bottom - top >= source->getHeight()) + bottom = top + source->getHeight() - 1; if (x < 0) { left -= x; @@ -157,256 +287,120 @@ void Video::drawSprite(SurfaceDesc *source, SurfaceDesc *dest, top -= y; y = 0; } - if (left > right) - return; - if (top > bottom) - return; - - if (x >= dest->width) - return; - - if (y >= dest->height) + if ((x >= dest->getWidth()) || (left > right) || + (y >= dest->getHeight()) || (top > bottom)) return; destRight = x + right - left; destBottom = y + bottom - top; - if (destRight >= dest->width) - right -= destRight - dest->width + 1; + if (destRight >= dest->getWidth()) + right -= destRight - dest->getWidth() + 1; - if (destBottom >= dest->height) - bottom -= destBottom - dest->height + 1; + if (destBottom >= dest->getHeight()) + bottom -= destBottom - dest->getHeight() + 1; } _videoDriver->drawSprite(source, dest, left, top, right, bottom, x, y, transp); } -void Video::fillRect(SurfaceDesc *dest, int16 left, int16 top, int16 right, int16 bottom, - int16 color) { - int16 temp; - - if (_vm->_global->_doRangeClamp) { - if (left > right) { - temp = left; - left = right; - right = temp; - } - if (top > bottom) { - temp = top; - top = bottom; - bottom = temp; - } - if (right < 0) - return; - if (bottom < 0) - return; - if (left >= dest->width) - return; - if (top >= dest->height) +void Video::drawLetter(int16 item, int16 x, int16 y, FontDesc *fontDesc, + int16 color1, int16 color2, int16 transp, SurfaceDesc *dest) { + char *dataPtr; + char *itemData; + int16 itemSize; + int16 newItem; + int16 curItem; + int16 newItemPos; + int16 curItemPos; + + if (fontDesc->endItem == 0) { + itemSize = fontDesc->itemSize + 3; + dataPtr = fontDesc->dataPtr; + // startItem + curItem = dataPtr[-2] - 1; + + curItemPos = 0; + do { + newItemPos = ((curItemPos + curItem) / 2) * itemSize; + itemData = fontDesc->dataPtr + newItemPos; + newItem = (READ_LE_UINT16(itemData) & 0x7FFF); + if (item > newItem) + curItem = newItemPos - 1; + else + curItemPos = newItemPos + 1; + } while ((newItem != item) && (curItemPos <= curItem)); + + if (newItem != item) return; - left = Video::clampValue(left, dest->width); - top = Video::clampValue(top, dest->height); - right = Video::clampValue(right, dest->width); - bottom = Video::clampValue(bottom, dest->height); + fontDesc->dataPtr = itemData + 3; + item = 0; } - _videoDriver->fillRect(dest, left, top, right, bottom, color); -} - -void Video::drawLine(SurfaceDesc *dest, int16 x0, int16 y0, int16 x1, int16 y1, int16 color) { - if (x0 == x1 || y0 == y1) { - Video::fillRect(dest, x0, y0, x1, y1, color); - return; - } - - _videoDriver->drawLine(dest, x0, y0, x1, y1, color); -} - -void Video::putPixel(int16 x, int16 y, int16 color, SurfaceDesc *dest) { - if (x < 0 || y < 0 || x >= dest->width || y >= dest->height) - return; - - _videoDriver->putPixel(x, y, color, dest); -} - -void Video::clearSurf(SurfaceDesc *dest) { - Video::fillRect(dest, 0, 0, dest->width - 1, dest->height - 1, 0); -} - -void Video::drawCircle(Video::SurfaceDesc *dest, int16 x, int16 y, int16 radius, int16 color) { - int16 si; - int16 var_18; - int16 var_16; - int16 y4; - int16 y3; - int16 x4; - int16 x3; - int16 x2; - int16 y2; - int16 x1; - int16 y1; - int16 var_4; - int16 var_2; - - var_2 = radius; - var_4 = 0; - si = -radius; - y1 = y; - x1 = x + radius; - y2 = y + radius; - x2 = x; - x3 = x - radius; - x4 = x; - y3 = y; - y4 = y - radius; - var_16 = 0; - var_18 = radius * 2; - - while (var_2 >= var_4) { - putPixel(x1, y1, color, dest); - putPixel(x2, y2, color, dest); - putPixel(x3, y1, color, dest); - putPixel(x4, y2, color, dest); - putPixel(x1, y3, color, dest); - putPixel(x2, y4, color, dest); - putPixel(x3, y3, color, dest); - putPixel(x4, y4, color, dest); - y1++; - x2++; - x4--; - y3--; - var_16 += 2; - var_4++; - si += var_16 + 1; - if (si > 0) { - x1--; - y2--; - x3++; - y4++; - var_18 -= 2; - var_2--; - si -= var_18 + 1; - } - } + _videoDriver->drawLetter((unsigned char) item, x, y, fontDesc, color1, color2, transp, dest); } -void Video::drawPackedSprite(byte *sprBuf, int16 width, int16 height, int16 x, int16 y, - int16 transp, SurfaceDesc *dest) { +void Video::drawPackedSprite(byte *sprBuf, int16 width, int16 height, + int16 x, int16 y, int16 transp, SurfaceDesc *dest) { if (spriteUncompressor(sprBuf, width, height, x, y, transp, dest)) return; - if (((dest->vidMode & 0x7f) != 0x13) && ((dest->vidMode & 0x7f) != 0x14)) - error("Video::drawPackedSprite: Video mode 0x%x is not fully supported!", - dest->vidMode & 0x7f); + _vm->validateVideoMode(dest->_vidMode); _videoDriver->drawPackedSprite(sprBuf, width, height, x, y, transp, dest); } -void Video::drawPackedSprite(const char *path, SurfaceDesc * dest, int width) { +void Video::drawPackedSprite(const char *path, SurfaceDesc *dest, int width) { char *data; - data = _vm->_dataio->getData(path); - drawPackedSprite((byte *) data, width, dest->height, 0, 0, 0, dest); + data = _vm->_dataIO->getData(path); + drawPackedSprite((byte *) data, width, dest->getHeight(), 0, 0, 0, dest); delete[] data; } -void Video::setPalElem(int16 index, char red, char green, char blue, int16 unused, - int16 vidMode) { +void Video::setPalElem(int16 index, char red, char green, char blue, + int16 unused, int16 vidMode) { byte pal[4]; + _vm->validateVideoMode(vidMode); + _vm->_global->_redPalette[index] = red; _vm->_global->_greenPalette[index] = green; _vm->_global->_bluePalette[index] = blue; + setPalColor(pal, red, green, blue); - if ((vidMode != 0x13) && (vidMode != 0x14)) - error("Video::setPalElem: Video mode 0x%x is not supported!", - vidMode); - - pal[0] = (red << 2) | (red >> 4); - pal[1] = (green << 2) | (green >> 4); - pal[2] = (blue << 2) | (blue >> 4); - pal[3] = 0; g_system->setPalette(pal, index, 1); } void Video::setPalette(PalDesc *palDesc) { - int16 i; byte pal[1024]; int16 numcolors; - if ((_vm->_global->_videoMode != 0x13) && (_vm->_global->_videoMode != 0x14)) - error("Video::setPalette: Video mode 0x%x is not supported!", - _vm->_global->_videoMode); - - if (_vm->_global->_setAllPalette) - numcolors = 256; - else - numcolors = 16; + _vm->validateVideoMode(_vm->_global->_videoMode); - for (i = 0; i < numcolors; i++) { - pal[i * 4 + 0] = (palDesc->vgaPal[i].red << 2) | (palDesc->vgaPal[i].red >> 4); - pal[i * 4 + 1] = (palDesc->vgaPal[i].green << 2) | (palDesc->vgaPal[i].green >> 4); - pal[i * 4 + 2] = (palDesc->vgaPal[i].blue << 2) | (palDesc->vgaPal[i].blue >> 4); - pal[i * 4 + 3] = 0; - } + numcolors = _vm->_global->_setAllPalette ? 256 : 16; + for (int i = 0; i < numcolors; i++) + setPalColor(pal + i * 4, palDesc->vgaPal[i]); g_system->setPalette(pal, 0, numcolors); } void Video::setFullPalette(PalDesc *palDesc) { - Color *colors; - int16 i; - byte pal[1024]; - if (_vm->_global->_setAllPalette) { - colors = palDesc->vgaPal; - for (i = 0; i < 256; i++) { + byte pal[1024]; + Color *colors = palDesc->vgaPal; + + for (int i = 0; i < 256; i++) { _vm->_global->_redPalette[i] = colors[i].red; _vm->_global->_greenPalette[i] = colors[i].green; _vm->_global->_bluePalette[i] = colors[i].blue; + setPalColor(pal + i * 4, colors[i]); } - for (i = 0; i < 256; i++) { - pal[i * 4 + 0] = (colors[i].red << 2) | (colors[i].red >> 4); - pal[i * 4 + 1] = (colors[i].green << 2) | (colors[i].green >> 4); - pal[i * 4 + 2] = (colors[i].blue << 2) | (colors[i].blue >> 4); - pal[i * 4 + 3] = 0; - } g_system->setPalette(pal, 0, 256); - } else { + } else Video::setPalette(palDesc); - } } -void Video::initPrimary(int16 mode) { - int16 old; - if (mode != 0x13 && mode != 0x14 && mode != 3 && mode != -1) - error("Video::initPrimary: Video mode 0x%x is not supported!", - mode); - - if ((_vm->_global->_videoMode != 0x13) && (_vm->_global->_videoMode != 0x14)) - error("Video::initPrimary: Video mode 0x%x is not supported!", - mode); - - old = _vm->_global->_oldMode; - if (mode == -1) - mode = 3; - - _vm->_global->_oldMode = mode; - if (mode != 3) - Video::initDriver(mode); - - if (mode != 3) { - initSurfDesc(mode, _surfWidth, _vm->_video->_surfHeight, PRIMARY_SURFACE); - - if (_vm->_global->_dontSetPalette) - return; - - Video::setFullPalette(_vm->_global->_pPaletteDesc); - } -} - -void Video::setHandlers() { _vm->_global->_setAllPalette = 1; } - -} // End of namespace Gob +} // End of namespace Gob diff --git a/engines/gob/video.h b/engines/gob/video.h index 99127e64bb..a896a1e2a0 100644 --- a/engines/gob/video.h +++ b/engines/gob/video.h @@ -20,39 +20,43 @@ * $Id$ * */ + #ifndef GOB_VIDEO_H #define GOB_VIDEO_H -#include "common/stdafx.h" -#include "common/util.h" #include "gob/gob.h" namespace Gob { -#define VID_SET_CURSOR(val) { _AH = 1; _CX = (val); geninterrupt(0x10); } -#define VID_RESTORE_MODE { _AX = 3; geninterrupt(0x10); } - -#define TEXT_VID_SEG 0xB800 -#define TEXT_VID_OFF 0 -#define TEXT_COL_COUNT 80 -#define TEXT_ROW_COUNT 25 - -extern int16 setAllPalette; +// Some Surfaces are simultaneous in Draw::spritesArray and discrete +// variables, so it's a references counting class that cleans +// up its own mess +class SurfaceDesc : public ReferenceCounter<SurfaceDesc> { +public: + int16 _vidMode; + + int16 getWidth() { return _width; } + int16 getHeight() { return _height; } + byte *getVidMem() { return _vidMem; } + bool hasOwnVidMem() { return _ownVidMem; } + + void setVidMem(byte *vidMem); + void resize(int16 width, int16 height); + void swap(SurfaceDesc &surf); + void swap(SurfaceDesc *surf) { assert(surf); swap(*surf); } + + SurfaceDesc(int16 vidMode, int16 width, int16 height, byte *vidMem = 0); + ~SurfaceDesc() { if (_ownVidMem) delete[] _vidMem; } + +private: + int16 _width; + int16 _height; + byte *_vidMem; + bool _ownVidMem; +}; class Video { public: - struct SurfaceDesc { - int16 width; - int16 height; - int8 reserved1; - int8 flag; - int16 vidMode; - byte *vidPtr; - int16 reserved2; - SurfaceDesc() : width(0), height(0), reserved1(0), flag(0), - vidMode(0), vidPtr(0), reserved2(0) {} - }; - struct FontDesc { char *dataPtr; int8 itemWidth; @@ -90,42 +94,56 @@ public: PalDesc() : vgaPal(0), unused1(0), unused2(0) {} }; + bool _doRangeClamp; int16 _surfWidth; int16 _surfHeight; int16 _scrollOffsetX; int16 _scrollOffsetY; - Video(class GobEngine *vm); - virtual ~Video() {}; - int32 getRectSize(int16 width, int16 height, int16 flag, int16 mode); - void freeSurfDesc(SurfaceDesc * surfDesc); - int16 clampValue(int16 val, int16 max); - void drawSprite(SurfaceDesc * source, SurfaceDesc * dest, int16 left, - int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp); - void fillRect(SurfaceDesc * dest, int16 left, int16 top, int16 right, int16 bottom, - int16 color); - void drawLine(SurfaceDesc * dest, int16 x0, int16 y0, int16 x1, int16 y1, - int16 color); - void putPixel(int16 x, int16 y, int16 color, SurfaceDesc * dest); - void drawCircle(Video::SurfaceDesc *dest, int16 x, int16 y, int16 radius, int16 color); - void clearSurf(SurfaceDesc * dest); - void drawPackedSprite(byte *sprBuf, int16 width, int16 height, int16 x, int16 y, - int16 transp, SurfaceDesc * dest); - void drawPackedSprite(const char *path, SurfaceDesc * dest, int width = 320); - void setPalElem(int16 index, char red, char green, char blue, int16 unused, - int16 vidMode); - void setPalette(PalDesc * palDesc); - void setFullPalette(PalDesc * palDesc); + void freeDriver(); void initPrimary(int16 mode); - void freeDriver(void); - void setHandlers(); + SurfaceDesc *initSurfDesc(int16 vidMode, int16 width, + int16 height, int16 flags); + void waitRetrace(bool mouse = true); + + void putPixel(int16 x, int16 y, int16 color, SurfaceDesc *dest); + void fillRect(SurfaceDesc *dest, int16 left, int16 top, + int16 right, int16 bottom, int16 color); + void drawLine(SurfaceDesc *dest, int16 x0, int16 y0, int16 x1, int16 y1, + int16 color); + void drawCircle(SurfaceDesc *dest, int16 x0, int16 y0, + int16 radius, int16 color); + void clearSurf(SurfaceDesc *dest); + void drawSprite(SurfaceDesc *source, SurfaceDesc *dest, + int16 left, int16 top, int16 right, int16 bottom, + int16 x, int16 y, int16 transp); + void drawLetter(int16 item, int16 x, int16 y, FontDesc *fontDesc, + int16 color1, int16 color2, int16 transp, SurfaceDesc *dest); + void drawPackedSprite(byte *sprBuf, int16 width, int16 height, + int16 x, int16 y, int16 transp, SurfaceDesc *dest); + void drawPackedSprite(const char *path, SurfaceDesc *dest, + int width = 320); + + void setPalColor(byte *pal, byte red, byte green, byte blue) { + pal[0] = red << 2; + pal[1] = green << 2; + pal[2] = blue << 2; + pal[3] = 0; + } + void setPalColor(byte *pal, Color &color) { + setPalColor(pal, color.red, color.green, color.blue); + } + void setPalElem(int16 index, char red, char green, char blue, + int16 unused, int16 vidMode); + void setPalette(PalDesc *palDesc); + void setFullPalette(PalDesc *palDesc); + + virtual char spriteUncompressor(byte *sprBuf, int16 srcWidth, + int16 srcHeight, int16 x, int16 y, int16 transp, + SurfaceDesc *destDesc) = 0; - virtual void drawLetter(int16 item, int16 x, int16 y, FontDesc * fontDesc, - int16 color1, int16 color2, int16 transp, SurfaceDesc * dest) = 0; - virtual SurfaceDesc *initSurfDesc(int16 vidMode, int16 width, int16 height, int16 flags) = 0; - virtual void waitRetrace(int16, bool mouse = true) = 0; - virtual char spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, - int16 x, int16 y, int16 transp, SurfaceDesc * destDesc) = 0; + Video(class GobEngine *vm); + virtual ~Video() {}; protected: class VideoDriver *_videoDriver; @@ -136,12 +154,8 @@ protected: class Video_v1 : public Video { public: - virtual void drawLetter(int16 item, int16 x, int16 y, FontDesc * fontDesc, - int16 color1, int16 color2, int16 transp, SurfaceDesc * dest); - virtual SurfaceDesc *initSurfDesc(int16 vidMode, int16 width, int16 height, int16 flags); - virtual void waitRetrace(int16, bool mouse = true); virtual char spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, - int16 x, int16 y, int16 transp, SurfaceDesc * destDesc); + int16 x, int16 y, int16 transp, SurfaceDesc *destDesc); Video_v1(GobEngine *vm); virtual ~Video_v1() {}; @@ -149,12 +163,8 @@ public: class Video_v2 : public Video_v1 { public: - virtual void drawLetter(int16 item, int16 x, int16 y, FontDesc * fontDesc, - int16 color1, int16 color2, int16 transp, SurfaceDesc * dest); - virtual SurfaceDesc *initSurfDesc(int16 vidMode, int16 width, int16 height, int16 flags); - virtual void waitRetrace(int16, bool mouse = true); virtual char spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, - int16 x, int16 y, int16 transp, SurfaceDesc * destDesc); + int16 x, int16 y, int16 transp, SurfaceDesc *destDesc); Video_v2(GobEngine *vm); virtual ~Video_v2() {}; @@ -164,14 +174,14 @@ class VideoDriver { public: VideoDriver() {} virtual ~VideoDriver() {} - virtual void drawSprite(Video::SurfaceDesc *source, Video::SurfaceDesc *dest, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp) = 0; - virtual void fillRect(Video::SurfaceDesc *dest, int16 left, int16 top, int16 right, int16 bottom, byte color) = 0; - virtual void putPixel(int16 x, int16 y, byte color, Video::SurfaceDesc *dest) = 0; - virtual void drawLetter(unsigned char item, int16 x, int16 y, Video::FontDesc *fontDesc, byte color1, byte color2, byte transp, Video::SurfaceDesc *dest) = 0; - virtual void drawLine(Video::SurfaceDesc *dest, int16 x0, int16 y0, int16 x1, int16 y1, byte color) = 0; - virtual void drawPackedSprite(byte *sprBuf, int16 width, int16 height, int16 x, int16 y, byte transp, Video::SurfaceDesc *dest) = 0; + virtual void drawSprite(SurfaceDesc *source, SurfaceDesc *dest, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp) = 0; + virtual void fillRect(SurfaceDesc *dest, int16 left, int16 top, int16 right, int16 bottom, byte color) = 0; + virtual void putPixel(int16 x, int16 y, byte color, SurfaceDesc *dest) = 0; + virtual void drawLetter(unsigned char item, int16 x, int16 y, Video::FontDesc *fontDesc, byte color1, byte color2, byte transp, SurfaceDesc *dest) = 0; + virtual void drawLine(SurfaceDesc *dest, int16 x0, int16 y0, int16 x1, int16 y1, byte color) = 0; + virtual void drawPackedSprite(byte *sprBuf, int16 width, int16 height, int16 x, int16 y, byte transp, SurfaceDesc *dest) = 0; }; -} // End of namespace Gob +} // End of namespace Gob -#endif +#endif // GOB_VIDEO_H diff --git a/engines/gob/video_v1.cpp b/engines/gob/video_v1.cpp index 15e6f9045e..c77098e790 100644 --- a/engines/gob/video_v1.cpp +++ b/engines/gob/video_v1.cpp @@ -23,128 +23,32 @@ #include "common/stdafx.h" #include "common/endian.h" -#include "graphics/cursorman.h" #include "gob/gob.h" -#include "gob/global.h" #include "gob/video.h" -#include "gob/draw.h" -#include "gob/util.h" namespace Gob { Video_v1::Video_v1(GobEngine *vm) : Video(vm) { } -//XXX: Use this function to update the screen for now. -// This should be moved to a better location later on. -void Video_v1::waitRetrace(int16, bool mouse) { - uint32 time; - - if (mouse) - CursorMan.showMouse((_vm->_draw->_showCursor & 2) != 0); - if (_vm->_global->_pPrimarySurfDesc) { - time = _vm->_util->getTimeKey(); - g_system->copyRectToScreen(_vm->_global->_pPrimarySurfDesc->vidPtr, 320, 0, 0, 320, 200); - g_system->updateScreen(); - _vm->_util->delay(MAX(1, 10 - (int)(_vm->_util->getTimeKey() - time))); - } -} - -void Video_v1::drawLetter(int16 item, int16 x, int16 y, FontDesc *fontDesc, int16 color1, - int16 color2, int16 transp, SurfaceDesc *dest) { - - _videoDriver->drawLetter((unsigned char) item, x, y, fontDesc, color1, color2, transp, dest); -} - -Video::SurfaceDesc *Video_v1::initSurfDesc(int16 vidMode, int16 width, int16 height, int16 flags) { - int8 flagsAnd2; - byte *vidMem = 0; - int32 sprSize; - int16 someFlags = 1; - SurfaceDesc *descPtr; - - if (flags != PRIMARY_SURFACE) - _vm->_global->_sprAllocated++; - - if (flags & RETURN_PRIMARY) - return _vm->_global->_pPrimarySurfDesc; - - if (vidMode != 0x13) - error("Video::initSurfDesc: Only VGA 0x13 mode is supported!"); - - if ((flags & PRIMARY_SURFACE) == 0) - vidMode += 0x80; - - if (flags & 2) - flagsAnd2 = 1; - else - flagsAnd2 = 0; - - if (flags & PRIMARY_SURFACE) { - _vm->_global->_primaryWidth = width; - _vm->_global->_mouseMaxCol = width; - _vm->_global->_primaryHeight = height; - _vm->_global->_mouseMaxRow = height; - sprSize = 0; - } else { - sprSize = Video::getRectSize(width, height, flagsAnd2, vidMode); - if (flagsAnd2) - someFlags += 0x80; - } - if (flags & PRIMARY_SURFACE) { - descPtr = _vm->_global->_pPrimarySurfDesc; - delete[] descPtr->vidPtr; - assert(descPtr); - vidMem = new byte[320 * 200]; - } else { - if (flags & DISABLE_SPR_ALLOC) { - descPtr = new SurfaceDesc; - // this case causes vidPtr to be set to invalid memory - assert(false); - } else { - descPtr = new SurfaceDesc; - descPtr->vidPtr = new byte[sprSize]; - vidMem = descPtr->vidPtr; - } - } - if (descPtr == 0) - return 0; - - descPtr->width = width; - descPtr->height = height; - descPtr->flag = someFlags; - descPtr->vidMode = vidMode; - descPtr->vidPtr = vidMem; - - descPtr->reserved1 = 0; - descPtr->reserved2 = 0; - return descPtr; -} - char Video_v1::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, int16 x, int16 y, int16 transp, SurfaceDesc *destDesc) { - SurfaceDesc sourceDesc; byte *memBuffer; - byte *srcPtr; - byte *destPtr; - byte *linePtr; + byte *srcPtr, *destPtr, *linePtr; byte temp; uint16 sourceLeft; - int16 curWidth; - int16 curHeight; + uint16 cmdVar; + int16 curWidth, curHeight; int16 offset; int16 counter2; - uint16 cmdVar; int16 bufPos; int16 strLen; if (!destDesc) return 1; - if ((destDesc->vidMode & 0x7f) != 0x13) - error("Video::spriteUncompressor: Video mode 0x%x is not supported!", - destDesc->vidMode & 0x7f); + _vm->validateVideoMode(destDesc->_vidMode); if (sprBuf[0] != 1) return 0; @@ -153,22 +57,18 @@ char Video_v1::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, return 0; if (sprBuf[2] == 2) { - sourceDesc.width = srcWidth; - sourceDesc.height = srcHeight; - sourceDesc.vidMode = 0x93; - sourceDesc.vidPtr = sprBuf + 3; + SurfaceDesc sourceDesc(0x13, srcWidth, srcHeight, sprBuf + 3); Video::drawSprite(&sourceDesc, destDesc, 0, 0, srcWidth - 1, srcHeight - 1, x, y, transp); return 1; } else { memBuffer = new byte[4114]; - if (memBuffer == 0) - return 0; + assert(memBuffer); srcPtr = sprBuf + 3; sourceLeft = READ_LE_UINT16(srcPtr); - destPtr = destDesc->vidPtr + destDesc->width * y + x; + destPtr = destDesc->getVidMem() + destDesc->getWidth() * y + x; curWidth = 0; curHeight = 0; @@ -184,18 +84,18 @@ char Video_v1::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, while (1) { cmdVar >>= 1; if ((cmdVar & 0x100) == 0) { - cmdVar = *srcPtr | 0xff00; + cmdVar = *srcPtr | 0xFF00; srcPtr++; } if ((cmdVar & 1) != 0) { temp = *srcPtr++; - if (temp != 0 || transp == 0) + if ((temp != 0) || (transp == 0)) *destPtr = temp; destPtr++; curWidth++; if (curWidth >= srcWidth) { curWidth = 0; - linePtr += destDesc->width; + linePtr += destDesc->getWidth(); destPtr = linePtr; curHeight++; if (curHeight >= srcHeight) @@ -211,23 +111,20 @@ char Video_v1::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, } else { offset = *srcPtr; srcPtr++; - offset |= (*srcPtr & 0xf0) << 4; - strLen = (*srcPtr & 0x0f) + 3; + offset |= (*srcPtr & 0xF0) << 4; + strLen = (*srcPtr & 0x0F) + 3; srcPtr++; - for (counter2 = 0; counter2 < strLen; - counter2++) { - temp = - memBuffer[(offset + - counter2) % 4096]; - if (temp != 0 || transp == 0) + for (counter2 = 0; counter2 < strLen; counter2++) { + temp = memBuffer[(offset + counter2) % 4096]; + if ((temp != 0) || (transp == 0)) *destPtr = temp; destPtr++; curWidth++; if (curWidth >= srcWidth) { curWidth = 0; - linePtr += destDesc->width; + linePtr += destDesc->getWidth(); destPtr = linePtr; curHeight++; if (curHeight >= srcHeight) { diff --git a/engines/gob/video_v2.cpp b/engines/gob/video_v2.cpp index 69515f27d9..e20c900180 100644 --- a/engines/gob/video_v2.cpp +++ b/engines/gob/video_v2.cpp @@ -23,175 +23,33 @@ #include "common/stdafx.h" #include "common/endian.h" -#include "graphics/cursorman.h" #include "gob/gob.h" -#include "gob/global.h" #include "gob/video.h" -#include "gob/draw.h" -#include "gob/util.h" namespace Gob { Video_v2::Video_v2(GobEngine *vm) : Video_v1(vm) { } -//XXX: Use this function to update the screen for now. -// This should be moved to a better location later on. -void Video_v2::waitRetrace(int16, bool mouse) { - uint32 time; - - if (mouse) - CursorMan.showMouse((_vm->_draw->_showCursor & 2) != 0); - if (_vm->_draw->_frontSurface) { - time = _vm->_util->getTimeKey(); - g_system->copyRectToScreen(_vm->_draw->_frontSurface->vidPtr + - _scrollOffsetY * _surfWidth + _scrollOffsetX, _surfWidth, - 0, 0, 320, 200); - g_system->updateScreen(); - _vm->_util->delay(MAX(1, 10 - (int)(_vm->_util->getTimeKey() - time))); - } -} - -void Video_v2::drawLetter(int16 item, int16 x, int16 y, FontDesc *fontDesc, int16 color1, - int16 color2, int16 transp, SurfaceDesc *dest) { - int16 videoMode; - - videoMode = dest->vidMode; - - // Is that needed at all? And what does it do anyway? - char *dataPtr; - int16 itemSize; - int16 si; - int16 di; - int16 dx; - char *var_A; - int16 var_10; - if (fontDesc->endItem == 0) { - itemSize = fontDesc->itemSize + 3; - dataPtr = fontDesc->dataPtr; - var_10 = dataPtr[-2] - 1; - si = 0; - do { - di = ((si + var_10) / 2) * itemSize; - var_A = fontDesc->dataPtr + di; - dx = (READ_LE_UINT16(var_A) & 0x7FFF); - if (item > dx) - var_10 = di - 1; - else - si = di + 1; - } while ((dx != item) && (si <= var_10)); - if (dx != item) - return; - fontDesc->dataPtr = var_A + 3; - item = 0; - } - - dest->vidMode &= 0x7F; - _videoDriver->drawLetter((unsigned char) item, x, y, fontDesc, color1, color2, transp, dest); - dest->vidMode = videoMode; -} - -Video::SurfaceDesc *Video_v2::initSurfDesc(int16 vidMode, int16 width, int16 height, int16 flags) { - int8 flagsAnd2; - byte *vidMem = 0; - int32 sprSize; - int16 someFlags = 1; - SurfaceDesc *descPtr; - - if ((_vm->_platform == Common::kPlatformAmiga) || - (_vm->_platform == Common::kPlatformAtariST)) - flags &= ~RETURN_PRIMARY; - - if (flags != PRIMARY_SURFACE) - _vm->_global->_sprAllocated++; - - if (flags & RETURN_PRIMARY) - return _vm->_draw->_frontSurface; - - if ((vidMode != 0x13) && (vidMode != 0x14)) - error("Video::initSurfDesc: Only VGA 0x13 mode is supported!"); - - if ((flags & PRIMARY_SURFACE) == 0) - vidMode += 0x80; - - if (flags & 2) - flagsAnd2 = 1; - else - flagsAnd2 = 0; - - if ((flags & SCUMMVM_CURSOR) == 0) - width = (width + 7) & 0xFFF8; - - if (flags & PRIMARY_SURFACE) { - _vm->_global->_primaryWidth = width; - _vm->_global->_mouseMaxCol = width; - _vm->_global->_primaryHeight = height; - _vm->_global->_mouseMaxRow = height; - sprSize = 0; - } else { - vidMem = 0; - sprSize = Video::getRectSize(width, height, flagsAnd2, vidMode); - someFlags = 4; - if (flagsAnd2) - someFlags += 0x80; - } - if (flags & PRIMARY_SURFACE) { - descPtr = _vm->_draw->_frontSurface; - assert(descPtr); - if (descPtr->vidPtr != 0) - delete[] descPtr->vidPtr; - vidMem = new byte[_surfWidth * _surfHeight]; - memset(vidMem, 0, _surfWidth * _surfHeight); - } else { - if (flags & DISABLE_SPR_ALLOC) { - descPtr = new SurfaceDesc; - // this case causes vidPtr to be set to invalid memory - assert(false); - } else { - descPtr = new SurfaceDesc; - descPtr->vidPtr = new byte[sprSize]; - memset(descPtr->vidPtr, 0, sprSize); - vidMem = descPtr->vidPtr; - } - } - if (descPtr == 0) - return 0; - - descPtr->width = width; - descPtr->height = height; - descPtr->flag = someFlags; - descPtr->vidMode = vidMode; - descPtr->vidPtr = vidMem; - - descPtr->reserved1 = 0; - descPtr->reserved2 = 0; - return descPtr; -} - char Video_v2::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, int16 x, int16 y, int16 transp, SurfaceDesc *destDesc) { - SurfaceDesc sourceDesc; byte *memBuffer; - byte *srcPtr; - byte *destPtr; - byte *linePtr; + byte *srcPtr, *destPtr, *linePtr; byte temp; uint32 sourceLeft; - int16 curWidth; - int16 curHeight; + uint16 cmdVar; + int16 curWidth, curHeight; int16 offset; int16 counter2; - uint16 cmdVar; int16 bufPos; int16 strLen; + int16 lenCmd; if (!destDesc) return 1; - if (((destDesc->vidMode & 0x7f) != 0x13) && ((destDesc->vidMode & 0x7f) != 0x14)) - error("Video::spriteUncompressor: Video mode 0x%x is not supported!", - destDesc->vidMode & 0x7f); + _vm->validateVideoMode(destDesc->_vidMode); if (sprBuf[0] != 1) return 0; @@ -200,22 +58,18 @@ char Video_v2::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, return 0; if (sprBuf[2] == 2) { - sourceDesc.width = srcWidth; - sourceDesc.height = srcHeight; - sourceDesc.vidMode = 0x93; - sourceDesc.vidPtr = sprBuf + 3; + SurfaceDesc sourceDesc(0x13, srcWidth, srcHeight, sprBuf + 3); Video::drawSprite(&sourceDesc, destDesc, 0, 0, srcWidth - 1, srcHeight - 1, x, y, transp); return 1; } else if (sprBuf[2] == 1) { memBuffer = new byte[4370]; - if (memBuffer == 0) - return 0; + assert(memBuffer); srcPtr = sprBuf + 3; sourceLeft = READ_LE_UINT32(srcPtr); - destPtr = destDesc->vidPtr + destDesc->width * y + x; + destPtr = destDesc->getVidMem() + destDesc->getWidth() * y + x; curWidth = 0; curHeight = 0; @@ -223,20 +77,14 @@ char Video_v2::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, linePtr = destPtr; srcPtr += 4; - int16 var_2E = 0; - int16 var_2F; - if ((READ_LE_UINT16(srcPtr + 2) == 0x5678) && (READ_LE_UINT16(srcPtr) != 0x1234)) { + if ((READ_LE_UINT16(srcPtr) == 0x1234) && (READ_LE_UINT16(srcPtr + 2) == 0x5678)) { srcPtr += 4; bufPos = 273; - var_2F = 18; + lenCmd = 18; } else { - var_2F = 100; + lenCmd = 100; bufPos = 4078; } - if (transp == 0) - var_2E = 300; - else - var_2E = 0; memset(memBuffer, 32, bufPos); @@ -244,18 +92,18 @@ char Video_v2::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, while (1) { cmdVar >>= 1; if ((cmdVar & 0x100) == 0) { - cmdVar = *srcPtr | 0xff00; + cmdVar = *srcPtr | 0xFF00; srcPtr++; } if ((cmdVar & 1) != 0) { temp = *srcPtr++; - if (temp != var_2E) + if ((temp != 0) || (transp == 0)) *destPtr = temp; destPtr++; curWidth++; if (curWidth >= srcWidth) { curWidth = 0; - linePtr += destDesc->width; + linePtr += destDesc->getWidth(); destPtr = linePtr; curHeight++; if (curHeight >= srcHeight) @@ -269,23 +117,22 @@ char Video_v2::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, break; } else { offset = *srcPtr++; - offset |= (*srcPtr & 0xf0) << 4; - strLen = (*srcPtr & 0x0f) + 3; + offset |= (*srcPtr & 0xF0) << 4; + strLen = (*srcPtr & 0x0F) + 3; *srcPtr++; - if (strLen == var_2F) + if (strLen == lenCmd) strLen = *srcPtr++ + 18; - for (counter2 = 0; counter2 < strLen; - counter2++) { + for (counter2 = 0; counter2 < strLen; counter2++) { temp = memBuffer[(offset + counter2) % 4096]; - if (temp != var_2E) + if ((temp != 0) || (transp == 0)) *destPtr = temp; destPtr++; curWidth++; if (curWidth >= srcWidth) { curWidth = 0; - linePtr += destDesc->width; + linePtr += destDesc->getWidth(); destPtr = linePtr; curHeight++; if (curHeight >= srcHeight) { @@ -297,14 +144,12 @@ char Video_v2::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, bufPos++; bufPos %= 4096; } - // loc_1D4E4 - if (strLen < (int32) sourceLeft) - sourceLeft--; - else { + if (strLen >= ((int32) sourceLeft)) { delete[] memBuffer; return 1; - } + } else + sourceLeft--; } } } else |