Initial commit
This commit is contained in:
161
engines/dgds/parser.cpp
Normal file
161
engines/dgds/parser.cpp
Normal file
@@ -0,0 +1,161 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "common/textconsole.h"
|
||||
#include "common/str.h"
|
||||
#include "common/stream.h"
|
||||
#include "dgds/includes.h"
|
||||
#include "dgds/resource.h"
|
||||
#include "dgds/parser.h"
|
||||
#include "dgds/scripts.h"
|
||||
#include "dgds/ttm.h"
|
||||
#include "dgds/ads.h"
|
||||
|
||||
namespace Dgds {
|
||||
|
||||
DgdsParser::DgdsParser(ResourceManager *resman, Decompressor *decompressor) :
|
||||
_resman(resman), _decompressor(decompressor), _bytesRead(0) {
|
||||
}
|
||||
|
||||
bool DgdsParser::parse(ParserData *data, const Common::String &filename) {
|
||||
DGDS_EX ex;
|
||||
|
||||
_filename = filename;
|
||||
Common::SeekableReadStream *resStream = _resman->getResource(filename);
|
||||
|
||||
if (!resStream) {
|
||||
error("Couldn't open script file '%s'", filename.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 dot = _filename.find('.');
|
||||
if (dot != Common::String::npos) {
|
||||
ex = MKTAG24(toupper(_filename[dot + 1]), toupper(_filename[dot + 2]), toupper(_filename[dot + 3]));
|
||||
} else {
|
||||
ex = 0;
|
||||
}
|
||||
|
||||
DgdsChunkReader chunk(resStream);
|
||||
while (chunk.readNextHeader(ex, _filename)) {
|
||||
bool stop;
|
||||
|
||||
if (chunk.isContainer()) {
|
||||
stop = handleChunk(chunk, data);
|
||||
} else {
|
||||
chunk.readContent(_decompressor);
|
||||
stop = handleChunk(chunk, data);
|
||||
}
|
||||
|
||||
if (stop)
|
||||
break;
|
||||
}
|
||||
|
||||
delete resStream;
|
||||
return true;
|
||||
}
|
||||
|
||||
Common::HashMap<uint16, Common::String> DgdsParser::readTags(Common::SeekableReadStream *stream) {
|
||||
Common::HashMap<uint16, Common::String> tags;
|
||||
uint16 count = stream->readUint16LE();
|
||||
debug(1, " %u tags:", count);
|
||||
|
||||
for (uint16 i = 0; i < count; i++) {
|
||||
uint16 idx = stream->readUint16LE();
|
||||
const Common::String tagVal = stream->readString();
|
||||
debug(1, " %2u: %2u, \"%s\"", i, idx, tagVal.c_str());
|
||||
// TODO: How to handle when these IDs overlap? (eg, see
|
||||
// BBEDROOM.TTM in RotD)
|
||||
if (!tags.contains(idx))
|
||||
tags[idx] = tagVal;
|
||||
}
|
||||
|
||||
return tags;
|
||||
}
|
||||
|
||||
|
||||
bool TTMParser::handleChunk(DgdsChunkReader &chunk, ParserData *data) {
|
||||
TTMEnviro *scriptData = static_cast<TTMEnviro *>(data);
|
||||
|
||||
switch (chunk.getId()) {
|
||||
case ID_TTI: // Ignore containers
|
||||
break;
|
||||
case ID_TT3:
|
||||
// Make a memory read stream from the chunk data
|
||||
scriptData->scr = chunk.makeMemoryStream();
|
||||
break;
|
||||
case ID_TAG:
|
||||
scriptData->_tags = readTags(chunk.getContent());
|
||||
break;
|
||||
case ID_VER: // Version - ignore
|
||||
break;
|
||||
case ID_PAG:
|
||||
if (chunk.getSize() != 2) {
|
||||
warning("unspected PAG chunk size %d in %s", chunk.getSize(), _filename.c_str());
|
||||
break;
|
||||
}
|
||||
scriptData->_totalFrames = chunk.getContent()->readUint16LE();
|
||||
scriptData->_frameOffsets.resize(scriptData->_totalFrames + 1, -1);
|
||||
break;
|
||||
default:
|
||||
debug("TTMParser: Unexpected chunk '%s' of size %d found in file '%s'", tag2str(chunk.getId()), chunk.getSize(), _filename.c_str());
|
||||
//chunk._contentStream->skip(chunk._size);
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool ADSParser::handleChunk(DgdsChunkReader &chunk, ParserData *data) {
|
||||
ADSData *scriptData = static_cast<ADSData *>(data);
|
||||
Common::SeekableReadStream *chunkStream = chunk.getContent();
|
||||
switch (chunk.getId()) {
|
||||
case EX_ADS:
|
||||
case ID_TTI: // Ignore containers
|
||||
break;
|
||||
case ID_RES: {
|
||||
uint16 count = chunkStream->readUint16LE();
|
||||
|
||||
for (uint16 i = 0; i < count; i++) {
|
||||
uint16 idx = chunkStream->readUint16LE();
|
||||
//assert(idx == (i + 1)); // not true in Willy Beamish.
|
||||
if (idx > scriptData->_scriptNames.size())
|
||||
scriptData->_scriptNames.resize(idx);
|
||||
|
||||
scriptData->_scriptNames[idx - 1] = chunkStream->readString();
|
||||
}
|
||||
} break;
|
||||
case ID_SCR:
|
||||
scriptData->scr = chunk.makeMemoryStream();
|
||||
break;
|
||||
case ID_TAG:
|
||||
scriptData->_tags = readTags(chunkStream);
|
||||
break;
|
||||
case ID_VER: // Version - ignore
|
||||
break;
|
||||
default:
|
||||
warning("ADSParser: Unexpected chunk '%s' of size %d found in file '%s'", tag2str(chunk.getId()), chunk.getSize(), _filename.c_str());
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // End of namespace Dgds
|
||||
Reference in New Issue
Block a user