mirror of
https://github.com/libretro/scummvm.git
synced 2025-03-01 07:46:11 +00:00
* Adapted Kyra to the new IFFParser interface.
* Adapted the new IFFParser to Kyra (slightly). The Kyra1 demo on the website works. svn-id: r41468
This commit is contained in:
parent
36828287ad
commit
b2e5905327
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
_avtlChunkSize = 0;
|
||||
_filename = filename;
|
||||
|
||||
_tim = new TIM;
|
||||
assert(_tim);
|
||||
memset(_tim, 0, sizeof(TIM));
|
||||
|
||||
_tim->procFunc = -1;
|
||||
_tim->opcodes = opcodes;
|
||||
|
||||
IFFParser iff(*stream);
|
||||
Common::IFFChunk *chunk = 0;
|
||||
Common::Functor1Mem< Common::IFFChunk &, bool, TIMInterpreter > c(this, &TIMInterpreter::callback);
|
||||
iff.parse(c);
|
||||
|
||||
TIM *tim = new TIM;
|
||||
assert(tim);
|
||||
memset(tim, 0, sizeof(TIM));
|
||||
|
||||
tim->procFunc = -1;
|
||||
tim->opcodes = opcodes;
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user