00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "engines/stark/formats/xrc.h"
00024
00025 #include "engines/stark/formats/xarc.h"
00026 #include "engines/stark/resources/anim.h"
00027 #include "engines/stark/resources/animhierarchy.h"
00028 #include "engines/stark/resources/animscript.h"
00029 #include "engines/stark/resources/animsoundtrigger.h"
00030 #include "engines/stark/resources/bonesmesh.h"
00031 #include "engines/stark/resources/bookmark.h"
00032 #include "engines/stark/resources/camera.h"
00033 #include "engines/stark/resources/container.h"
00034 #include "engines/stark/resources/command.h"
00035 #include "engines/stark/resources/dialog.h"
00036 #include "engines/stark/resources/direction.h"
00037 #include "engines/stark/resources/fmv.h"
00038 #include "engines/stark/resources/image.h"
00039 #include "engines/stark/resources/item.h"
00040 #include "engines/stark/resources/floor.h"
00041 #include "engines/stark/resources/floorface.h"
00042 #include "engines/stark/resources/floorfield.h"
00043 #include "engines/stark/resources/knowledge.h"
00044 #include "engines/stark/resources/knowledgeset.h"
00045 #include "engines/stark/resources/layer.h"
00046 #include "engines/stark/resources/level.h"
00047 #include "engines/stark/resources/light.h"
00048 #include "engines/stark/resources/lipsync.h"
00049 #include "engines/stark/resources/location.h"
00050 #include "engines/stark/resources/path.h"
00051 #include "engines/stark/resources/pattable.h"
00052 #include "engines/stark/resources/root.h"
00053 #include "engines/stark/resources/script.h"
00054 #include "engines/stark/resources/scroll.h"
00055 #include "engines/stark/resources/speech.h"
00056 #include "engines/stark/resources/sound.h"
00057 #include "engines/stark/resources/string.h"
00058 #include "engines/stark/resources/textureset.h"
00059 #include "engines/stark/resourcereference.h"
00060
00061 namespace Stark {
00062 namespace Formats {
00063
00064 XRCReadStream::XRCReadStream(const Common::String &archiveName,
00065 Common::SeekableReadStream *parentStream, DisposeAfterUse::Flag disposeParentStream) :
00066 SeekableSubReadStream(parentStream, 0, parentStream->size(), disposeParentStream),
00067 _archiveName(archiveName) {
00068 }
00069
00070 XRCReadStream::~XRCReadStream() {
00071 }
00072
00073 Common::String XRCReadStream::readString() {
00074
00075 uint16 length = readUint16LE();
00076
00077
00078 char *data = new char[length];
00079 read(data, length);
00080 Common::String string(data, length);
00081 delete[] data;
00082
00083 return string;
00084 }
00085
00086 Resources::Type XRCReadStream::readResourceType() {
00087 byte rawType;
00088 rawType = readByte();
00089 return Resources::Type((Resources::Type::ResourceType) (rawType));
00090 }
00091
00092 ResourceReference XRCReadStream::readResourceReference() {
00093 ResourceReference reference;
00094 reference.loadFromStream(this);
00095
00096 return reference;
00097 }
00098
00099 Math::Vector3d XRCReadStream::readVector3() {
00100 Math::Vector3d v;
00101 v.readFromStream(this);
00102 return v;
00103 }
00104
00105 Common::Rect XRCReadStream::readRect() {
00106 Common::Rect r;
00107 r.left = readSint32LE();
00108 r.top = readSint32LE();
00109 r.right = readSint32LE();
00110 r.bottom = readSint32LE();
00111 return r;
00112 }
00113
00114 Common::Point XRCReadStream::readPoint() {
00115 uint32 x = readUint32LE();
00116 uint32 y = readUint32LE();
00117
00118 return Common::Point(x, y);
00119 }
00120
00121 bool XRCReadStream::readBool() {
00122 uint32 b = readUint32LE();
00123 return b != 0;
00124 }
00125
00126 bool XRCReadStream::isDataLeft() {
00127 return pos() < size();
00128 }
00129
00130 Common::String XRCReadStream::getArchiveName() const {
00131 return _archiveName;
00132 }
00133
00134 Resources::Object *XRCReader::importTree(XARCArchive *archive) {
00135
00136 Common::ArchiveMemberList members;
00137 archive->listMatchingMembers(members, "*.xrc");
00138 if (members.size() == 0) {
00139 error("No resource tree in archive '%s'", archive->getFilename().c_str());
00140 }
00141 if (members.size() > 1) {
00142 error("Too many resource scripts in archive '%s'", archive->getFilename().c_str());
00143 }
00144
00145
00146 Common::SeekableReadStream *stream = archive->createReadStreamForMember(members.front()->getName());
00147 XRCReadStream *xrcStream = new XRCReadStream(archive->getFilename(), stream);
00148
00149
00150 Resources::Object *root = importResource(xrcStream, nullptr);
00151
00152 delete xrcStream;
00153
00154 return root;
00155 }
00156
00157 Resources::Object *XRCReader::importResource(XRCReadStream *stream, Resources::Object *parent) {
00158 Resources::Object *resource = createResource(stream, parent);
00159 importResourceData(stream, resource);
00160 importResourceChildren(stream, resource);
00161
00162
00163 resource->onPostRead();
00164
00165 return resource;
00166 }
00167
00168 Resources::Object *XRCReader::createResource(XRCReadStream *stream, Resources::Object *parent) {
00169
00170 Resources::Type type = stream->readResourceType();
00171 byte subType = stream->readByte();
00172
00173
00174 uint16 index = stream->readUint16LE();
00175 Common::String name = stream->readString();
00176
00177
00178 Resources::Object *resource;
00179 switch (type.get()) {
00180 case Resources::Type::kRoot:
00181 resource = new Resources::Root(parent, subType, index, name);
00182 break;
00183 case Resources::Type::kLevel:
00184 resource = new Resources::Level(parent, subType, index, name);
00185 break;
00186 case Resources::Type::kLocation:
00187 resource = new Resources::Location(parent, subType, index, name);
00188 break;
00189 case Resources::Type::kLayer:
00190 resource = Resources::Layer::construct(parent, subType, index, name);
00191 break;
00192 case Resources::Type::kCamera:
00193 resource = new Resources::Camera(parent, subType, index, name);
00194 break;
00195 case Resources::Type::kFloor:
00196 resource = new Resources::Floor(parent, subType, index, name);
00197 break;
00198 case Resources::Type::kFloorFace:
00199 resource = new Resources::FloorFace(parent, subType, index, name);
00200 break;
00201 case Resources::Type::kItem:
00202 resource = Resources::Item::construct(parent, subType, index, name);
00203 break;
00204 case Resources::Type::kScript:
00205 resource = new Resources::Script(parent, subType, index, name);
00206 break;
00207 case Resources::Type::kAnimHierarchy:
00208 resource = new Resources::AnimHierarchy(parent, subType, index, name);
00209 break;
00210 case Resources::Type::kAnim:
00211 resource = Resources::Anim::construct(parent, subType, index, name);
00212 break;
00213 case Resources::Type::kDirection:
00214 resource = new Resources::Direction(parent, subType, index, name);
00215 break;
00216 case Resources::Type::kImage:
00217 resource = Resources::Image::construct(parent, subType, index, name);
00218 break;
00219 case Resources::Type::kAnimScript:
00220 resource = new Resources::AnimScript(parent, subType, index, name);
00221 break;
00222 case Resources::Type::kAnimScriptItem:
00223 resource = new Resources::AnimScriptItem(parent, subType, index, name);
00224 break;
00225 case Resources::Type::kSoundItem:
00226 resource = new Resources::Sound(parent, subType, index, name);
00227 break;
00228 case Resources::Type::kPath:
00229 resource = Resources::Path::construct(parent, subType, index, name);
00230 break;
00231 case Resources::Type::kFloorField:
00232 resource = new Resources::FloorField(parent, subType, index, name);
00233 break;
00234 case Resources::Type::kBookmark:
00235 resource = new Resources::Bookmark(parent, subType, index, name);
00236 break;
00237 case Resources::Type::kKnowledgeSet:
00238 resource = new Resources::KnowledgeSet(parent, subType, index, name);
00239 break;
00240 case Resources::Type::kKnowledge:
00241 resource = new Resources::Knowledge(parent, subType, index, name);
00242 break;
00243 case Resources::Type::kCommand:
00244 resource = new Resources::Command(parent, subType, index, name);
00245 break;
00246 case Resources::Type::kPATTable:
00247 resource = new Resources::PATTable(parent, subType, index, name);
00248 break;
00249 case Resources::Type::kContainer:
00250 resource = new Resources::Container(parent, subType, index, name);
00251 break;
00252 case Resources::Type::kDialog:
00253 resource = new Resources::Dialog(parent, subType, index, name);
00254 break;
00255 case Resources::Type::kSpeech:
00256 resource = new Resources::Speech(parent, subType, index, name);
00257 break;
00258 case Resources::Type::kLight:
00259 resource = new Resources::Light(parent, subType, index, name);
00260 break;
00261 case Resources::Type::kBonesMesh:
00262 resource = new Resources::BonesMesh(parent, subType, index, name);
00263 break;
00264 case Resources::Type::kScroll:
00265 resource = new Resources::Scroll(parent, subType, index, name);
00266 break;
00267 case Resources::Type::kFMV:
00268 resource = new Resources::FMV(parent, subType, index, name);
00269 break;
00270 case Resources::Type::kLipSync:
00271 resource = new Resources::LipSync(parent, subType, index, name);
00272 break;
00273 case Resources::Type::kAnimSoundTrigger:
00274 resource = new Resources::AnimSoundTrigger(parent, subType, index, name);
00275 break;
00276 case Resources::Type::kString:
00277 resource = new Resources::String(parent, subType, index, name);
00278 break;
00279 case Resources::Type::kTextureSet:
00280 resource = new Resources::TextureSet(parent, subType, index, name);
00281 break;
00282 default:
00283 resource = new Resources::UnimplementedResource(parent, type, subType, index, name);
00284 break;
00285 }
00286
00287 return resource;
00288 }
00289
00290 void XRCReader::importResourceData(XRCReadStream *stream, Resources::Object *resource) {
00291
00292 uint32 dataLength = stream->readUint32LE();
00293
00294
00295 if (dataLength > 0) {
00296 XRCReadStream *xrcDataStream = new XRCReadStream(stream->getArchiveName(), stream->readStream(dataLength));
00297
00298 resource->readData(xrcDataStream);
00299
00300 if (xrcDataStream->isDataLeft()) {
00301 warning("Not all XRC data was read. Type %s, subtype %d, name %s",
00302 resource->getType().getName(), resource->getSubType(), resource->getName().c_str());
00303 }
00304
00305 if (xrcDataStream->eos()) {
00306 warning("Too much XRC data was read. Type %s, subtype %d, name %s",
00307 resource->getType().getName(), resource->getSubType(), resource->getName().c_str());
00308 }
00309
00310 delete xrcDataStream;
00311 }
00312 }
00313
00314 void XRCReader::importResourceChildren(XRCReadStream *stream, Resources::Object *resource) {
00315
00316 uint16 numChildren = stream->readUint16LE();
00317
00318
00319 uint16 unknown3 = stream->readUint16LE();
00320 if (unknown3 != 0) {
00321 warning("Stark::XRCReader: \"%s\" has unknown3=0x%04X with unknown meaning", resource->getName().c_str(), unknown3);
00322 }
00323
00324
00325 for (int i = 0; i < numChildren; i++) {
00326 Resources::Object *child = importResource(stream, resource);
00327
00328
00329 resource->addChild(child);
00330 }
00331 }
00332
00333 }
00334 }