ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

xrc.cpp

Go to the documentation of this file.
00001 /* ResidualVM - A 3D game interpreter
00002  *
00003  * ResidualVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the AUTHORS
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
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     // Read the string length
00075     uint16 length = readUint16LE();
00076 
00077     // Read the string
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     // Find the XRC file
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     // Open the XRC file
00146     Common::SeekableReadStream *stream = archive->createReadStreamForMember(members.front()->getName());
00147     XRCReadStream *xrcStream = new XRCReadStream(archive->getFilename(), stream);
00148 
00149     // Import the resource tree
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     // Resource lifecycle update
00163     resource->onPostRead();
00164 
00165     return resource;
00166 }
00167 
00168 Resources::Object *XRCReader::createResource(XRCReadStream *stream, Resources::Object *parent) {
00169     // Read the resource type and subtype
00170     Resources::Type type = stream->readResourceType();
00171     byte subType = stream->readByte();
00172 
00173     // Read the resource properties
00174     uint16 index = stream->readUint16LE();
00175     Common::String name = stream->readString();
00176 
00177     // Create a new resource
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     // Read the data length
00292     uint32 dataLength = stream->readUint32LE();
00293 
00294     // Read the resource type specific data using a memory stream
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     // Get the number of children
00316     uint16 numChildren = stream->readUint16LE();
00317 
00318     // Read more unknown data
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     // Read the children resources
00325     for (int i = 0; i < numChildren; i++) {
00326         Resources::Object *child = importResource(stream, resource);
00327 
00328         // Add child to parent
00329         resource->addChild(child);
00330     }
00331 }
00332 
00333 } // End of namespace Formats
00334 } // End of namespace Stark


Generated on Sat Apr 20 2019 05:04:21 for ResidualVM by doxygen 1.7.1
curved edge   curved edge