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  | 
