UString debugTag(uint32 tag, bool trim) { UString str; if (tagToString(tag, trim, str)) return UString::format("0x%08X ('%s')", FROM_BE_32(tag), str.c_str()); return UString::format("0x%08X", FROM_BE_32(tag)); }
void Chore::fade(Animation::FadeMode mode, uint msecs) { for (int i = 0; i < _numTracks; i++) { Component *comp = _owner->_components[_tracks[i].compID]; if (comp && FROM_BE_32(comp->getTag()) == MKTAG('K','E','Y','F')) { KeyframeComponent *kf = static_cast<KeyframeComponent *>(comp); kf->fade(mode, msecs); } } }
ModelComponent *Costume::getMainModelComponent() const { for (int i = 0; i < _numComponents; i++) { // Needs to handle Main Models (pigeons) and normal Models // (when Manny climbs the rope) if (FROM_BE_32(_components[i]->getTag()) == MKTAG('M','M','D','L')) return static_cast<ModelComponent *>(_components[i]); } return NULL; }
void MaterialComponent::init() { _mat = NULL; if (FROM_BE_32(_parent->getTag()) == MKTAG('M','M','D','L') || FROM_BE_32(_parent->getTag()) == MKTAG('M','O','D','L')) { ModelComponent *p = static_cast<ModelComponent *>(_parent); Model *model = p->getModel(); if (model) { for (int i = 0; i < model->_numMaterials; ++i) { if (_filename.compareToIgnoreCase(model->_materials[i]->getFilename()) == 0) { _mat = model->_materials[i]; return; } } } } else { warning("Parent of a MaterialComponent not a ModelComponent. %s %s", _filename.c_str(), _cost->getFilename().c_str()); } }
static GFFVersion identifyGFF(Common::SeekableReadStream &input, bool allowNWNPremium) { uint32 id = 0xFFFFFFFF, version = 0xFFFFFFFF; try { size_t pos = input.pos(); id = input.readUint32BE(); version = input.readUint32BE(); input.seek(pos); } catch (...) { throw; } GFFVersion gffVersion; if ((version == kVersion32) || (version == kVersion33)) { gffVersion = kGFFVersion3; allowNWNPremium = false; } else if ((version == kVersion40) || (version == kVersion41)) { gffVersion = kGFFVersion4; allowNWNPremium = false; } else if (allowNWNPremium && (FROM_BE_32(id) >= 0x30) && (FROM_BE_32(id) <= 0x12F)) { gffVersion = kGFFVersion3; } else throw Common::Exception("Invalid GFF %s, %s", Common::debugTag(id).c_str(), Common::debugTag(version).c_str()); size_t foundType = 0xFFFFFFFF; for (size_t i = 0; i < ARRAYSIZE(kGFFTypes); i++) { if (kGFFTypes[i] == id) { foundType = i; break; } } if ((foundType == 0xFFFFFFFF) && !allowNWNPremium) warning("Unknown GFF type %s", Common::debugTag(id).c_str()); return gffVersion; }
Component *Costume::loadComponentEMI(Component *parent, int parentID, const char *name, Component *prevComponent) { // some have an exclimation mark, this could mean something. // for now, return 0 otherwise it will just crash in some other part. //return 0; assert(name[0] == '!'); ++name; char type[5]; tag32 tag = 0; memcpy(&tag, name, 4); memcpy(&type, name, 4); type[4] = 0; name += 4; if (FROM_BE_32(tag) == MKTAG('m','e','s','h')) { Debug::warning(Debug::Costumes, "Actor::loadComponentEMI Implement MESH-handling: %s" , name); //return new MainModelComponent(parent, parentID, name, prevComponent, tag); } else if (FROM_BE_32(tag) == MKTAG('s','k','e','l')) { Debug::warning(Debug::Costumes, "Actor::loadComponentEMI Implement SKEL-handling: %s" , name); //return new ModelComponent(parent, parentID, name, prevComponent, tag); } else if (FROM_BE_32(tag) == MKTAG('t','e','x','i')) { Debug::warning(Debug::Costumes, "Actor::loadComponentEMI Implement TEXI-handling: %s" , name); //return new MaterialComponent(parent, parentID, name, tag); } else if (FROM_BE_32(tag) == MKTAG('a','n','i','m')) { Debug::warning(Debug::Costumes, "Actor::loadComponentEMI Implement ANIM-handling: %s" , name); //return new KeyframeComponent(parent, parentID, name, tag); } else if (FROM_BE_32(tag) == MKTAG('l','u','a','c')) { Debug::warning(Debug::Costumes, "Actor::loadComponentEMI Implement LUAC-handling: %s" , name); } else if (FROM_BE_32(tag) == MKTAG('l','u','a','v')) { Debug::warning(Debug::Costumes, "Actor::loadComponentEMI Implement LUAV-handling: %s" , name); //return new LuaVarComponent(parent, parentID, name, tag); } else if (FROM_BE_32(tag) == MKTAG('s','p','r','t')) { Debug::warning(Debug::Costumes, "Actor::loadComponentEMI Implement SPRT-handling: %s" , name); //return new SpriteComponent(parent, parentID, name, tag); } else { error("Actor::loadComponentEMI missing tag: %s for %s", name, type); } /* char t[4]; memcpy(t, &tag, sizeof(tag32)); warning("loadComponent: Unknown tag '%c%c%c%c', name '%s'", t[0], t[1], t[2], t[3], name);*/ return NULL; }
Component *EMICostume::loadEMIComponent(Component *parent, int parentID, const char *name, Component *prevComponent) { assert(name[0] == '!'); ++name; char type[5]; tag32 tag = 0; memcpy(&tag, name, 4); memcpy(&type, name, 4); type[4] = 0; tag = FROM_BE_32(tag); name += 4; if (tag == MKTAG('m', 'e', 's', 'h')) { return new EMIMeshComponent(parent, parentID, name, prevComponent, tag, this); } else if (tag == MKTAG('s', 'k', 'e', 'l')) { return new EMISkelComponent(parent, parentID, name, prevComponent, tag); } else if (tag == MKTAG('t', 'e', 'x', 'i')) { return new EMITexiComponent(parent, parentID, name, prevComponent, tag); } else if (tag == MKTAG('a', 'n', 'i', 'm')) { return new EMIAnimComponent(parent, parentID, name, prevComponent, tag); } else if (tag == MKTAG('l', 'u', 'a', 'c')) { return new EMILuaCodeComponent(parent, parentID, name, prevComponent, tag); } else if (tag == MKTAG('l', 'u', 'a', 'v')) { return new EMILuaVarComponent(parent, parentID, name, prevComponent, tag); } else if (tag == MKTAG('s', 'p', 'r', 't')) { return new EMISpriteComponent(parent, parentID, name, prevComponent, tag); } else if (tag == MKTAG('s', 'h', 'a', 'd')) { Debug::warning(Debug::Costumes, "Actor::loadComponentEMI Implement SHAD-handling: %s" , name); } else if (tag == MKTAG('a', 'w', 'g', 't')) { Debug::warning(Debug::Costumes, "Actor::loadComponentEMI Implement AWGT-handling: %s" , name); } else if (tag == MKTAG('s', 'n', 'd', '2')) { // ignore, this is a leftover from an earlier engine. } else { error("Actor::loadComponentEMI missing tag: %s for %s", name, type); } return nullptr; }
Component *Costume::loadComponent (tag32 tag, Component *parent, int parentID, const char *name, Component *prevComponent) { if (FROM_BE_32(tag) == MKTAG('M','M','D','L')) return new MainModelComponent(parent, parentID, name, prevComponent, tag); else if (FROM_BE_32(tag) == MKTAG('M','O','D','L')) return new ModelComponent(parent, parentID, name, prevComponent, tag); else if (FROM_BE_32(tag) == MKTAG('C','M','A','P')) return new ColormapComponent(parent, parentID, name, tag); else if (FROM_BE_32(tag) == MKTAG('K','E','Y','F')) return new KeyframeComponent(parent, parentID, name, tag); else if (FROM_BE_32(tag) == MKTAG('M','E','S','H')) return new MeshComponent(parent, parentID, name, tag); else if (FROM_BE_32(tag) == MKTAG('L','U','A','V')) return new LuaVarComponent(parent, parentID, name, tag); else if (FROM_BE_32(tag) == MKTAG('I','M','L','S')) return new SoundComponent(parent, parentID, name, tag); else if (FROM_BE_32(tag) == MKTAG('B','K','N','D')) return new BitmapComponent(parent, parentID, name, tag); else if (FROM_BE_32(tag) == MKTAG('M','A','T',' ')) return new MaterialComponent(parent, parentID, name, tag); else if (FROM_BE_32(tag) == MKTAG('S','P','R','T')) return new SpriteComponent(parent, parentID, name, tag); else if (FROM_BE_32(tag) == MKTAG('A','N','I','M')) //Used in the demo return new BitmapComponent(parent, parentID, name, tag); char t[4]; memcpy(t, &tag, sizeof(tag32)); warning("loadComponent: Unknown tag '%c%c%c%c', name '%s'", t[0], t[1], t[2], t[3], name); return NULL; }
void Costume::load(Common::SeekableReadStream *data) { TextSplitter ts(_fname, data); ts.expectString("costume v0.1"); ts.expectString("section tags"); int numTags; ts.scanString(" numtags %d", 1, &numTags); tag32 *tags = new tag32[numTags]; for (int i = 0; i < numTags; i++) { unsigned char t[4]; int which; // Obtain a tag ID from the file ts.scanString(" %d '%c%c%c%c'", 5, &which, &t[0], &t[1], &t[2], &t[3]); // Force characters to upper case for (int j = 0; j < 4; j++) t[j] = toupper(t[j]); memcpy(&tags[which], t, sizeof(tag32)); tags[which] = FROM_BE_32(tags[which]); } ts.expectString("section components"); ts.scanString(" numcomponents %d", 1, &_numComponents); _components = new Component *[_numComponents]; for (int i = 0; i < _numComponents; i++) { int id, tagID, hash, parentID, namePos; const char *line = ts.getCurrentLine(); Component *prevComponent = NULL; if (sscanf(line, " %d %d %d %d %n", &id, &tagID, &hash, &parentID, &namePos) < 4) error("Bad component specification line: `%s'", line); ts.nextLine(); // A Parent ID of "-1" indicates that the component should // use the properties of the previous costume as a base if (parentID == -1) { if (_prevCostume) { // However, only the first item can actually share the // node hierarchy with the previous costume, so flag // that component so it knows what to do if (i == 0) parentID = -2; prevComponent = _prevCostume->_components[0]; // Make sure that the component is valid if (!prevComponent->isComponentType('M','M','D','L')) prevComponent = NULL; } else if (id > 0) { // Use the MainModelComponent of this costume as prevComponent, // so that the component can use its colormap. prevComponent = _components[0]; } } // Actually load the appropriate component _components[id] = loadComponent(tags[tagID], parentID < 0 ? NULL : _components[parentID], parentID, line + namePos, prevComponent); _components[id]->setCostume(this); } delete[] tags; for (int i = 0; i < _numComponents; i++) if (_components[i]) { _components[i]->init(); } ts.expectString("section chores"); ts.scanString(" numchores %d", 1, &_numChores); _chores = new Chore *[_numChores]; for (int i = 0; i < _numChores; i++) { int id, length, tracks; char name[32]; ts.scanString(" %d %d %d %32s", 4, &id, &length, &tracks, name); _chores[id] = new Chore(name, i, this, length, tracks); Debug::debug(Debug::Chores, "Loaded chore: %s\n", name); } ts.expectString("section keys"); for (int i = 0; i < _numChores; i++) { int which; ts.scanString("chore %d", 1, &which); _chores[which]->load(ts); } }