diff options
Diffstat (limited to 'engines')
-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 |
4 files changed, 98 insertions, 79 deletions
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; |