aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/kyra/script.cpp74
-rw-r--r--engines/kyra/script.h11
-rw-r--r--engines/kyra/script_tim.cpp85
-rw-r--r--engines/kyra/script_tim.h7
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;