diff options
| -rw-r--r-- | common/iff_container.h | 8 | ||||
| -rw-r--r-- | engines/kyra/script.cpp | 74 | ||||
| -rw-r--r-- | engines/kyra/script.h | 11 | ||||
| -rw-r--r-- | engines/kyra/script_tim.cpp | 85 | ||||
| -rw-r--r-- | engines/kyra/script_tim.h | 7 | 
5 files changed, 102 insertions, 83 deletions
diff --git a/common/iff_container.h b/common/iff_container.h index 8a1b934a30..3b5620ba60 100644 --- a/common/iff_container.h +++ b/common/iff_container.h @@ -216,9 +216,13 @@ class IFFParser {  		}  	}; +protected:  	IFFChunkNav _formChunk;	//!< The root chunk of the file.  	IFFChunkNav _chunk; 	//!< The current chunk. +	uint32 _formSize; +	Common::IFF_ID _formType; +  	Common::ReadStream *_stream;  	bool _disposeStream; @@ -292,10 +296,6 @@ public:  		} while (!stop);  	} - -private: -	uint32 _formSize; -	Common::IFF_ID _formType;  }; diff --git a/engines/kyra/script.cpp b/engines/kyra/script.cpp index 9035708f5e..0a60c9d154 100644 --- a/engines/kyra/script.cpp +++ b/engines/kyra/script.cpp @@ -66,6 +66,40 @@ EMCInterpreter::EMCInterpreter(KyraEngine_v1 *vm) : _vm(vm) {  #undef OPCODE  } +bool EMCInterpreter::callback(Common::IFFChunk &chunk) { +	switch (chunk._type) { +	case MKID_BE('TEXT'): +		_scriptData->text = new byte[chunk._size]; +		assert(_scriptData->text); +		if (chunk._stream->read(_scriptData->text, chunk._size) != chunk._size) +			error("Couldn't read TEXT chunk from file '%s'", _filename); +		break; + +	case MKID_BE('ORDR'): +		_scriptData->ordr = new uint16[chunk._size >> 1]; +		assert(_scriptData->ordr); +		if (chunk._stream->read(_scriptData->ordr, chunk._size) != chunk._size) +			error("Couldn't read ORDR chunk from file '%s'", _filename); + +		for (int i = (chunk._size >> 1) - 1; i >= 0; --i) +			_scriptData->ordr[i] = READ_BE_UINT16(&_scriptData->ordr[i]); +		break; + +	case MKID_BE('DATA'): +		_scriptData->data = new uint16[chunk._size >> 1]; +		assert(_scriptData->data); +		if (chunk._stream->read(_scriptData->data, chunk._size) != chunk._size) +			error("Couldn't read DATA chunk from file '%s'", _filename); + +		for (int i = (chunk._size >> 1) - 1; i >= 0; --i) +			_scriptData->data[i] = READ_BE_UINT16(&_scriptData->data[i]); +		break; + +	default: +		warning("Unexpected chunk '%s' of size %d found in file '%s'", Common::ID2string(chunk._type), chunk._size, _filename); +	} +} +  bool EMCInterpreter::load(const char *filename, EMCData *scriptData, const Common::Array<const Opcode*> *opcodes) {  	Common::SeekableReadStream *stream = _vm->resource()->createReadStream(filename);  	if (!stream) { @@ -75,42 +109,12 @@ bool EMCInterpreter::load(const char *filename, EMCData *scriptData, const Commo  	memset(scriptData, 0, sizeof(EMCData)); +	_scriptData = scriptData; +	_filename = filename; +  	IFFParser iff(*stream); -	Common::IFFChunk *chunk = 0; - -	while ((chunk = iff.nextChunk()) != 0) { -		switch (chunk->id) { -		case MKID_BE('TEXT'): -			scriptData->text = new byte[chunk->size]; -			assert(scriptData->text); -			if (chunk->read(scriptData->text, chunk->size) != chunk->size) -				error("Couldn't read TEXT chunk from file '%s'", filename); -			break; - -		case MKID_BE('ORDR'): -			scriptData->ordr = new uint16[chunk->size >> 1]; -			assert(scriptData->ordr); -			if (chunk->read(scriptData->ordr, chunk->size) != chunk->size) -				error("Couldn't read ORDR chunk from file '%s'", filename); - -			for (int i = (chunk->size >> 1) - 1; i >= 0; --i) -				scriptData->ordr[i] = READ_BE_UINT16(&scriptData->ordr[i]); -			break; - -		case MKID_BE('DATA'): -			scriptData->data = new uint16[chunk->size >> 1]; -			assert(scriptData->data); -			if (chunk->read(scriptData->data, chunk->size) != chunk->size) -				error("Couldn't read DATA chunk from file '%s'", filename); - -			for (int i = (chunk->size >> 1) - 1; i >= 0; --i) -				scriptData->data[i] = READ_BE_UINT16(&scriptData->data[i]); -			break; - -		default: -			warning("Unexpected chunk '%s' of size %d found in file '%s'", Common::ID2string(chunk->id), chunk->size, filename); -		} -	} +	Common::Functor1Mem< Common::IFFChunk &, bool, EMCInterpreter > c(this, &EMCInterpreter::callback); +	iff.parse(c);  	if (!scriptData->ordr)  		error("No ORDR chunk found in file: '%s'", filename); diff --git a/engines/kyra/script.h b/engines/kyra/script.h index 88bbe86c4d..7a46f40c09 100644 --- a/engines/kyra/script.h +++ b/engines/kyra/script.h @@ -70,7 +70,7 @@ class KyraEngine_v1;  class IFFParser : public Common::IFFParser {  public: -	IFFParser(Common::SeekableReadStream &input) : Common::IFFParser(input) { +	IFFParser(Common::ReadStream &input) : Common::IFFParser(&input) {  		// It seems Westwood missunderstood the 'size' field of the FORM chunk.  		//  		// For EMC scripts (type EMC2) it's filesize instead of filesize - 8, @@ -84,9 +84,9 @@ public:  		// Both lead to some problems in our IFF parser, either reading after the end  		// of file or producing a "Chunk overread" error message. To work around this  		// we need to adjust the size field properly. -		if (_typeId == MKID_BE('EMC2')) +		if (_formType == MKID_BE('EMC2'))  			_formChunk.size -= 8; -		else if (_typeId == MKID_BE('AVFS')) +		else if (_formType == MKID_BE('AVFS'))  			_formChunk.size += 4;  	}  }; @@ -108,6 +108,11 @@ protected:  	KyraEngine_v1 *_vm;  	int16 _parameter; +	const char *_filename; +	EMCData *_scriptData; + +	bool EMCInterpreter::callback(Common::IFFChunk &chunk); +  	typedef void (EMCInterpreter::*OpcodeProc)(EMCState *);  	struct OpcodeEntry {  		OpcodeProc proc; diff --git a/engines/kyra/script_tim.cpp b/engines/kyra/script_tim.cpp index 2beabf459a..ff82ceb1e5 100644 --- a/engines/kyra/script_tim.cpp +++ b/engines/kyra/script_tim.cpp @@ -116,6 +116,32 @@ TIMInterpreter::~TIMInterpreter() {  	delete[] _animations;  } +bool TIMInterpreter::callback(Common::IFFChunk &chunk) { +	switch (chunk._type) { +	case MKID_BE('TEXT'): +		_tim->text = new byte[chunk._size]; +		assert(_tim->text); +		if (chunk._stream->read(_tim->text, chunk._size) != chunk._size) +			error("Couldn't read TEXT chunk from file '%s'", _filename); +		break; + +	case MKID_BE('AVTL'): +		_avtlChunkSize = chunk._size >> 1; +		_tim->avtl = new uint16[_avtlChunkSize]; +		assert(_tim->avtl); +		if (chunk._stream->read(_tim->avtl, chunk._size) != chunk._size) +			error("Couldn't read AVTL chunk from file '%s'", _filename); + +		for (int i = _avtlChunkSize - 1; i >= 0; --i) +			_tim->avtl[i] = READ_LE_UINT16(&_tim->avtl[i]); +		break; + +	default: +		warning("Unexpected chunk '%s' of size %d found in file '%s'", Common::ID2string(chunk._type), chunk._size, _filename); +	} + +} +  TIM *TIMInterpreter::load(const char *filename, const Common::Array<const TIMOpcode *> *opcodes) {  	if (!_vm->resource()->exists(filename))  		return 0; @@ -124,44 +150,21 @@ TIM *TIMInterpreter::load(const char *filename, const Common::Array<const TIMOpc  	if (!stream)  		error("Couldn't open TIM file '%s'", filename); -	IFFParser iff(*stream); -	Common::IFFChunk *chunk = 0; - -	TIM *tim = new TIM; -	assert(tim); -	memset(tim, 0, sizeof(TIM)); +	_avtlChunkSize = 0; +	_filename = filename; -	tim->procFunc = -1; -	tim->opcodes = opcodes; +	_tim = new TIM; +	assert(_tim); +	memset(_tim, 0, sizeof(TIM)); -	int avtlChunkSize = 0; - -	while ((chunk = iff.nextChunk()) != 0) { -		switch (chunk->id) { -		case MKID_BE('TEXT'): -			tim->text = new byte[chunk->size]; -			assert(tim->text); -			if (chunk->read(tim->text, chunk->size) != chunk->size) -				error("Couldn't read TEXT chunk from file '%s'", filename); -			break; +	_tim->procFunc = -1; +	_tim->opcodes = opcodes; -		case MKID_BE('AVTL'): -			avtlChunkSize = chunk->size >> 1; -			tim->avtl = new uint16[avtlChunkSize]; -			assert(tim->avtl); -			if (chunk->read(tim->avtl, chunk->size) != chunk->size) -				error("Couldn't read AVTL chunk from file '%s'", filename); - -			for (int i = avtlChunkSize - 1; i >= 0; --i) -				tim->avtl[i] = READ_LE_UINT16(&tim->avtl[i]); -			break; - -		default: -			warning("Unexpected chunk '%s' of size %d found in file '%s'", Common::ID2string(chunk->id), chunk->size, filename); -		} -	} +	IFFParser iff(*stream); +	Common::Functor1Mem< Common::IFFChunk &, bool, TIMInterpreter > c(this, &TIMInterpreter::callback); +	iff.parse(c); -	if (!tim->avtl) +	if (!_tim->avtl)  		error("No AVTL chunk found in file: '%s'", filename);  	if (stream->err()) @@ -169,17 +172,17 @@ TIM *TIMInterpreter::load(const char *filename, const Common::Array<const TIMOpc  	delete stream; -	int num = (avtlChunkSize < TIM::kCountFuncs) ? avtlChunkSize : (int)TIM::kCountFuncs; +	int num = (_avtlChunkSize < TIM::kCountFuncs) ? _avtlChunkSize : (int)TIM::kCountFuncs;  	for (int i = 0; i < num; ++i) -		tim->func[i].avtl = tim->avtl + tim->avtl[i]; +		_tim->func[i].avtl = _tim->avtl + _tim->avtl[i]; -	strncpy(tim->filename, filename, 13); -	tim->filename[12] = 0; +	strncpy(_tim->filename, filename, 13); +	_tim->filename[12] = 0; -	tim->isLoLOutro = (_vm->gameFlags().gameID == GI_LOL) && !scumm_stricmp(filename, "LOLFINAL.TIM"); -	tim->lolCharacter = 0; +	_tim->isLoLOutro = (_vm->gameFlags().gameID == GI_LOL) && !scumm_stricmp(filename, "LOLFINAL.TIM"); +	_tim->lolCharacter = 0; -	return tim; +	return _tim;  }  void TIMInterpreter::unload(TIM *&tim) const { diff --git a/engines/kyra/script_tim.h b/engines/kyra/script_tim.h index 10337b4b09..40049c3dec 100644 --- a/engines/kyra/script_tim.h +++ b/engines/kyra/script_tim.h @@ -121,6 +121,8 @@ public:  	TIM *load(const char *filename, const Common::Array<const TIMOpcode*> *opcodes);  	void unload(TIM *&tim) const; +	bool callback(Common::IFFChunk &chunk); +  	virtual Animation *initAnimStruct(int index, const char *filename, int x, int y, int, int offscreenBuffer, uint16 wsaFlags);  	virtual int freeAnimStruct(int index); @@ -169,6 +171,11 @@ protected:  	bool _finished; +	// used when loading +	int _avtlChunkSize; +	const char *_filename; +	TIM *_tim; +  	Common::String _vocFiles[120];  	Animation *_animations;  | 
