void Placeable::load(const Aurora::GFF3Struct &placeable) { Common::UString temp = placeable.getString("TemplateResRef"); Aurora::GFF3File *utp = 0; if (!temp.empty()) { try { utp = new Aurora::GFF3File(temp, Aurora::kFileTypeUTP, MKTAG('U', 'T', 'P', ' ')); } catch (...) { } } Situated::load(placeable, utp ? &utp->getTopLevel() : 0); delete utp; }
void Waypoint::load(const Aurora::GFF3Struct &waypoint) { Common::UString temp = waypoint.getString("TemplateResRef"); Aurora::GFF3File *utw = 0; if (!temp.empty()) { try { utw = new Aurora::GFF3File(temp, Aurora::kFileTypeUTW, MKTAG('U', 'T', 'W', ' ')); } catch (...) { } } load(waypoint, utw ? &utw->getTopLevel() : 0); delete utw; }
void Walkmesh::load(const Common::UString &resRef) { clear(); Common::ScopedPtr<Common::SeekableReadStream> wok(ResMan.getResource(resRef, ::Aurora::kFileTypeWOK)); if (wok) { try { appendFromStream(*wok); } catch (Common::Exception &e) { warning("Walkmesh load failed: %s %s", resRef.c_str(), e.what()); } } else warning("Walkmesh file not found: %s", resRef.c_str()); refreshIndexGroups(); }
void Creature::loadModel() { if (!_modelParts.empty()) return; if (_appearanceID == Aurora::kFieldIDInvalid) { warning("Creature \"%s\" has no appearance", _tag.c_str()); return; } Common::UString body = getBaseModel("NWN2_Model_Body"); if (body.empty()) { warning("Creature \"%s\" has no body", _tag.c_str()); return; } // Main body model loadArmorModel(body, "BODY", _armorVisualType, _armorVariation); const Aurora::TwoDARow &appearance = TwoDAReg.get2DA("appearance").getRow(_appearanceID); if (appearance.getInt("BodyType") == 1) { // Creature with more part models than just the body loadHeadModel(_appearanceHead); loadHairModel(_appearanceMHair); loadHairModel(_appearanceFHair); loadArmorModel(body, "BOOTS" , _bootsVisualType, _bootsVariation); if (!loadArmorModel(body, "GLOVES", 10, 0)) loadArmorModel(body, "GLOVES", 0, 0); } // Positioning float x, y, z, angle; getPosition(x, y, z); setPosition(x, y, z); getOrientation(x, y, z, angle); setOrientation(x, y, z, angle); for (std::list<Graphics::Aurora::Model *>::iterator m = _modelParts.begin(); m != _modelParts.end(); ++m) { (*m)->setTag(_tag); (*m)->setClickable(isClickable()); _ids.push_back((*m)->getID()); } }
void TwoDAFile::readHeaders2b(Common::SeekableReadStream &twoda) { /* Read the column headers of a binary 2DA file. */ Common::StreamTokenizer tokenize(Common::StreamTokenizer::kRuleHeed); // Individual column headers a separated by either a tab or a NUL tokenize.addSeparator('\t'); tokenize.addSeparator('\0'); Common::UString header = tokenize.getToken(twoda); while (!header.empty()) { _headers.push_back(header); header = tokenize.getToken(twoda); } }
bool Creature::loadArmorModel(const Common::UString &body, const Common::UString &armor, uint8 visualType, uint8 variation) { const Aurora::TwoDARow &armorVisual = TwoDAReg.get2DA("armorvisualdata").getRow(visualType); Common::UString armorPrefix = armorVisual.getString("Prefix"); Common::UString modelFile; modelFile = Common::UString::format("%s_%s_%s%02d", body.c_str(), armorPrefix.c_str(), armor.c_str(), variation + 1); Graphics::Aurora::Model *model = loadModelObject(modelFile); if (model) _modelParts.push_back(model); return model != 0; }
Sound::ChannelHandle playSound(const Common::UString &sound, Sound::SoundType soundType, bool loop, float volume, bool pitchVariance) { Aurora::ResourceType resType = (soundType == Sound::kSoundTypeMusic) ? Aurora::kResourceMusic : Aurora::kResourceSound; Sound::ChannelHandle channel; try { Common::SeekableReadStream *soundStream = ResMan.getResource(resType, sound); if (!soundStream) return channel; channel = SoundMan.playSoundFile(soundStream, soundType, loop); debugC(Common::kDebugEngineSound, 1, "Playing sound \"%s\" in %s", sound.c_str(), SoundMan.formatChannel(channel).c_str()); SoundMan.setChannelGain(channel, volume); if (pitchVariance) { const float pitch = 1.0f + ((((std::rand() % 1001) / 1000.0f) / 5.0f) - 0.1f); SoundMan.setChannelPitch(channel, pitch); } SoundMan.startChannel(channel); } catch (...) { Common::exceptionDispatcherWarning(); } return channel; }
void AreaBackground::loadTexture(const Common::UString &name) { Common::SeekableReadStream *cbgt = 0, *pal = 0, *twoda = 0; Graphics::CBGT *image = 0; try { if (!(cbgt = ResMan.getResource(name, Aurora::kFileTypeCBGT))) throw Common::Exception("No such CBGT"); if (!(pal = ResMan.getResource(name, Aurora::kFileTypePAL))) throw Common::Exception("No such PAL"); if (!(twoda = ResMan.getResource(name, Aurora::kFileType2DA))) throw Common::Exception("No such 2DA"); image = new Graphics::CBGT(*cbgt, *pal, *twoda); _texture = TextureMan.add(Graphics::Aurora::Texture::create(image, Aurora::kFileTypeCBGT), name); } catch (Common::Exception &e) { delete image; delete cbgt; delete pal; delete twoda; e.add("Failed loading area background \"%s\"", name.c_str()); throw; } delete cbgt; delete pal; delete twoda; }
void Module::loadModule(const Common::UString &module, const Common::UString &entryLocation, ObjectType entryLocationType) { unload(false); _module = module; _entryLocation = entryLocation; _entryLocationType = entryLocationType; try { load(); } catch (Common::Exception &e) { _module.clear(); e.add("Failed loading module \"%s\"", module.c_str()); throw e; } _newModule.clear(); _hasModule = true; }
bool Module::getObjectLocation(const Common::UString &object, ObjectType location, float &entryX, float &entryY, float &entryZ, float &entryAngle) { if (object.empty()) return false; Aurora::NWScript::ObjectSearch *search = findObjectsByTag(object); KotOR::Object *kotorObject = 0; while (!kotorObject && search->get()) { kotorObject = KotOR::ObjectContainer::toObject(search->next()); if (!kotorObject || !(kotorObject->getType() & location)) kotorObject = 0; } delete search; if (!kotorObject) return false; // TODO: Entry orientation kotorObject->getPosition(entryX, entryY, entryZ); entryAngle = 0.0f; return true; }
void VideoPlayer::load(const Common::UString &name) { delete _video; _video = 0; ::Aurora::FileType type; Common::SeekableReadStream *video = ResMan.getResource(::Aurora::kResourceVideo, name, &type); if (!video) throw Common::Exception("No such video resource \"%s\"", name.c_str()); // Loading the different image formats switch (type) { case ::Aurora::kFileTypeBIK: _video = new Bink(video); break; case ::Aurora::kFileTypeMOV: _video = new QuickTimeDecoder(video); break; case ::Aurora::kFileTypeXMV: _video = new XboxMediaVideo(video); break; case ::Aurora::kFileTypeVX: _video = new ActimagineDecoder(video); break; default: delete video; throw Common::Exception("Unsupported video resource type %d", (int) type); } _video->setScale(VideoDecoder::kScaleUpDown); }
void printUsage(FILE *stream, const Common::UString &name) { std::fprintf(stream, "XML to BioWare TLK converter\n\n"); std::fprintf(stream, "Usage: %s [<options>] [<input file>] <output file>\n", name.c_str()); std::fprintf(stream, " -h --help This help text\n"); std::fprintf(stream, " --version Display version information\n"); std::fprintf(stream, " -3 --version30 Write a V3.0 TLK file\n"); std::fprintf(stream, " -4 --version40 Write a V4.0 TLK file\n"); std::fprintf(stream, " -l <id> --language <id> Override the TLK language ID\n\n"); std::fprintf(stream, " --cp1250 Write TLK strings as Windows CP-1250\n"); std::fprintf(stream, " --cp1251 Write TLK strings as Windows CP-1251\n"); std::fprintf(stream, " --cp1252 Write TLK strings as Windows CP-1252\n"); std::fprintf(stream, " --cp932 Write TLK strings as Windows CP-932\n"); std::fprintf(stream, " --cp936 Write TLK strings as Windows CP-936\n"); std::fprintf(stream, " --cp949 Write TLK strings as Windows CP-949\n"); std::fprintf(stream, " --cp950 Write TLK strings as Windows CP-950\n"); std::fprintf(stream, " --utf8 Write TLK strings as UTF-8\n"); std::fprintf(stream, " --utf16le Write TLK strings as little-endian UTF-16\n"); std::fprintf(stream, " --utf16be Write TLK strings as big-endian UTF-16\n\n"); std::fprintf(stream, " --nwn Use Neverwinter Nights encodings\n"); std::fprintf(stream, " --nwn2 Use Neverwinter Nights 2 encodings\n"); std::fprintf(stream, " --kotor Use Knights of the Old Republic encodings\n"); std::fprintf(stream, " --kotor2 Use Knights of the Old Republic II encodings\n"); std::fprintf(stream, " --jade Use Jade Empire encodings\n"); std::fprintf(stream, " --witcher Use The Witcher encodings\n"); std::fprintf(stream, " --dragonage Use Dragon Age encodings\n"); std::fprintf(stream, " --dragonage2 Use Dragon Age II encodings\n\n"); std::fprintf(stream, "If no input file is given, the input is read from stdin.\n\n"); std::fprintf(stream, "One of --version* to specify the version of TLK to write is mandatory,\n"); std::fprintf(stream, "as is one of the flags for the encoding. If the XML file provides a\n"); std::fprintf(stream, "language ID, the --language flag is optional.\n\n"); std::fprintf(stream, "There is no way to autodetect the encoding of strings in TLK files,\n"); std::fprintf(stream, "so an encoding must be specified. Alternatively, the game this TLK\n"); std::fprintf(stream, "is from can be given, and an appropriate encoding according to that\n"); std::fprintf(stream, "game and the language ID is used.\n"); }
void printUsage(FILE *stream, const Common::UString &name) { std::fprintf(stream, "BioWare TLK to XML converter\n\n"); std::fprintf(stream, "Usage: %s [<options>] <input file> [<output file>]\n", name.c_str()); std::fprintf(stream, " -h --help This help text\n"); std::fprintf(stream, " --version Display version information\n\n"); std::fprintf(stream, " --cp1250 Read TLK strings as Windows CP-1250\n"); std::fprintf(stream, " --cp1251 Read TLK strings as Windows CP-1251\n"); std::fprintf(stream, " --cp1252 Read TLK strings as Windows CP-1252\n"); std::fprintf(stream, " --cp932 Read TLK strings as Windows CP-932\n"); std::fprintf(stream, " --cp936 Read TLK strings as Windows CP-936\n"); std::fprintf(stream, " --cp949 Read TLK strings as Windows CP-949\n"); std::fprintf(stream, " --cp950 Read TLK strings as Windows CP-950\n"); std::fprintf(stream, " --utf8 Read TLK strings as UTF-8\n"); std::fprintf(stream, " --utf16le Read TLK strings as little-endian UTF-16\n"); std::fprintf(stream, " --utf16be Read TLK strings as big-endian UTF-16\n\n"); std::fprintf(stream, " --nwn Use Neverwinter Nights encodings\n"); std::fprintf(stream, " --nwn2 Use Neverwinter Nights 2 encodings\n"); std::fprintf(stream, " --kotor Use Knights of the Old Republic encodings\n"); std::fprintf(stream, " --kotor2 Use Knights of the Old Republic II encodings\n"); std::fprintf(stream, " --jade Use Jade Empire encodings\n"); std::fprintf(stream, " --witcher Use The Witcher encodings\n"); std::fprintf(stream, " --dragonage Use Dragon Age encodings\n"); std::fprintf(stream, " --dragonage2 Use Dragon Age II encodings\n\n"); std::fprintf(stream, "If no output file is given, the output is written to stdout.\n\n"); std::fprintf(stream, "There is no way to autodetect the encoding of strings in TLK files,\n"); std::fprintf(stream, "so an encoding must be specified. Alternatively, the game this TLK\n"); std::fprintf(stream, "is from can be given, and an appropriate encoding according to that\n"); std::fprintf(stream, "game and the language ID found in the TLK is used.\n"); }
void DialogBox::setEntry(const Common::UString &entry) { GfxMan.lockFrame(); clearEntry(); if (entry.empty()) { GfxMan.unlockFrame(); return; } _entry = TokenMan.parse(entry); // TODO: Check entry length, scrollbars const float maxWidth = _width - 2.0f - 2.0f - _portrait->getWidth() - 5.0f; std::vector<Common::UString> lines; _font.getFont().split(_entry, lines, maxWidth); for (std::vector<Common::UString>::iterator l = lines.begin(); l != lines.end(); ++l) _entryLines.push_back(new Graphics::Aurora::Text(_font, *l)); setPosition(_x, _y, _z); if (isVisible()) showEntry(); GfxMan.unlockFrame(); }
void Tooltip::addLine(const Common::UString &text, float r, float g, float b, float a) { hide(); if (text.empty()) return; std::vector<Common::UString> lines; Common::UString::split(text, '\n', lines); for (std::vector<Common::UString>::const_iterator l = lines.begin(); l != lines.end(); ++l) { _lines.push_back(Line()); _lines.back().r = r; _lines.back().g = g; _lines.back().b = b; _lines.back().a = a; _lines.back().line = *l; _lines.back().text = new Graphics::Aurora::Text(FontMan.get(getFontName()), *l, r, g, b, a); _lines.back().text->setTag("Tooltip#Text"); } redoLayout(); }
void convert(const Common::UString &inFile, const Common::UString &outFile, Aurora::FileType type, bool flip) { Common::ReadFile in(inFile); if (type == Aurora::kFileTypeNone) { // Detect by file contents type = detectType(in); if (type == Aurora::kFileTypeNone) { // Detect by file name type = detectType(inFile); if (type == Aurora::kFileTypeNone) throw Common::Exception("Failed to detect type of file \"%s\"", inFile.c_str()); } } Images::Decoder *image = openImage(in, type); if (flip) image->flipVertically(); try { image->dumpTGA(outFile); } catch (...) { delete image; throw; } delete image; }
void Room::loadLayout(const Common::UString &roomFile) { if (!ResMan.hasResource(roomFile, Aurora::kFileTypeRML) || EventMan.quitRequested()) return; GFF4File rml(roomFile, Aurora::kFileTypeRML, kRMLID); if (rml.getTypeVersion() != kVersion40) throw Common::Exception("Unsupported RML version %s", Common::debugTag(rml.getTypeVersion()).c_str()); const GFF4Struct &rmlTop = rml.getTopLevel(); float roomPos[3] = { 0.0f, 0.0f, 0.0f }; rmlTop.getVector3(kGFF4Position, roomPos[0], roomPos[1], roomPos[2]); float roomOrient[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; rmlTop.getVector4(kGFF4Orientation, roomOrient[0], roomOrient[1], roomOrient[2], roomOrient[3]); roomOrient[3] = Common::rad2deg(acos(roomOrient[3]) * 2.0); Common::Matrix4x4 roomTransform; roomTransform.translate(roomPos[0], roomPos[1], roomPos[2]); roomTransform.rotate(roomOrient[3], roomOrient[0], roomOrient[1], roomOrient[2]); status("Loading room \"%s\" (%d)", roomFile.c_str(), _id); const GFF4List &models = rmlTop.getList(kGFF4EnvRoomModelList); _models.reserve(models.size()); for (GFF4List::const_iterator m = models.begin(); m != models.end(); ++m) { if (!*m || ((*m)->getLabel() != kMDLID)) continue; float scale = (*m)->getFloat(kGFF4EnvModelScale); float pos[3] = { 0.0f, 0.0f, 0.0f }; (*m)->getVector3(kGFF4Position, pos[0], pos[1], pos[2]); float orient[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; (*m)->getVector4(kGFF4Orientation, orient[0], orient[1], orient[2], orient[3]); orient[3] = Common::rad2deg(acos(orient[3]) * 2.0); // TODO: Instances Graphics::Aurora::Model *model = loadModelObject((*m)->getString(kGFF4EnvModelFile)); if (!model) continue; _models.push_back(model); Common::Matrix4x4 modelTransform(roomTransform); modelTransform.translate(pos[0], pos[1], pos[2]); modelTransform.rotate(orient[3], orient[0], orient[1], orient[2]); modelTransform.getPosition(pos[0], pos[1], pos[2]); modelTransform.getAxisAngle(orient[3], orient[0], orient[1], orient[2]); model->setPosition(pos[0], pos[1], pos[2]); model->setOrientation(orient[0], orient[1], orient[2], orient[3]); model->setScale(scale, scale, scale); } }
void Texture::load(const Common::UString &name) { Common::SeekableReadStream *img = ResMan.getResource(::Aurora::kResourceImage, name, &_type); if (!img) throw Common::Exception("No such image resource \"%s\"", name.c_str()); _name = name; // Loading the different image formats if (_type == ::Aurora::kFileTypeTGA) _image = new TGA(*img); else if (_type == ::Aurora::kFileTypeDDS) _image = new DDS(*img); else if (_type == ::Aurora::kFileTypeTPC) _image = new TPC(*img); else if (_type == ::Aurora::kFileTypeTXB) _image = new TXB(*img); else if (_type == ::Aurora::kFileTypeSBM) _image = new SBM(*img); else { delete img; throw Common::Exception("Unsupported image resource type %d", (int) _type); } delete img; loadTXI(ResMan.getResource(name, ::Aurora::kFileTypeTXI)); loadImage(); }
Common::UString Area::getName(const Common::UString &resRef, const Common::UString &rimFile) { if (!rimFile.empty()) { try { Common::SeekableReadStream *rimStream = ResMan.getResource(rimFile, Aurora::kFileTypeRIM); if (!rimStream) throw 0; const Aurora::RIMFile rim(rimStream); const uint32 areIndex = rim.findResource(resRef, Aurora::kFileTypeARE); const GFF3File are(rim.getResource(areIndex), kAREID); return are.getTopLevel().getString("Name"); } catch (...) { } } try { const GFF3File are(resRef, Aurora::kFileTypeARE, kAREID); return are.getTopLevel().getString("Name"); } catch (...) { } return ""; }
GUIQuad::GUIQuad(Graphics::GUIElement::GUIElementType type, const Common::UString &texture, float x1 , float y1 , float x2 , float y2, float tX1, float tY1, float tX2, float tY2) : GUIElement(type), _r(1.0f), _g(1.0f), _b(1.0f), _a(1.0f), _angle(0.0f), _x1 (x1) , _y1 (y1) , _x2 (x2) , _y2 (y2) , _tX1(tX1), _tY1(tY1), _tX2(tX2), _tY2(tY2), _xscale(1.0f), _yscale(1.0f), _scissorX(0), _scissorY(0), _scissorWidth(0), _scissorHeight(0), _xor(false), _scissor(false), _blendMode(kBlendDefault), _material(0), _shaderRenderable() { try { if (!texture.empty()) _texture = TextureMan.get(texture); } catch (...) { _texture.clear(); _r = _g = _b = _a = 0.0f; } if (!_texture.empty() && (_texture.getTexture().getTXI().getFeatures().blending == TXI::kBlendingAdditive)) { _blendMode = kBlendAdditive; } _distance = -FLT_MAX; buildMaterial(); }
void WidgetButton::setIcon(const Common::UString &icon) { if (_icon == icon) return; _icon = icon; if (icon.empty()) { if (_iconQuad) { _iconQuad->hide(); _iconQuad.reset(); } return; } Graphics::Aurora::TextureHandle textureHandle = TextureMan.get(icon); Graphics::Aurora::Texture &texture = textureHandle.getTexture(); _iconQuad.reset(new Graphics::Aurora::GUIQuad( textureHandle, 0.0f, 0.0f, texture.getWidth(), texture.getHeight())); float x, y, z; getPosition(x, y, z); _iconQuad->setPosition( x + getWidth() / 2.0f - texture.getWidth() / 2.0f, y + getHeight() / 2.0f - texture.getHeight() / 2.0f, z - 1.0f ); if (isVisible()) _iconQuad->show(); }
void Object::playSound(const Common::UString &sound, bool pitchVariance) { stopSound(); if (sound.empty()) return; _sound = ::Engines::playSound(sound, Sound::kSoundTypeVoice, false, 1.0f, pitchVariance); }
void Object::loadSSF() { if (_ssf || (_soundSet == Aurora::kFieldIDInvalid)) return; const Aurora::TwoDAFile &soundSets = TwoDAReg.get2DA("soundset"); Common::UString ssfFile = soundSets.getRow(_soundSet).getString("RESREF"); if (ssfFile.empty()) return; try { _ssf = new Aurora::SSFFile(ssfFile); } catch (...) { warning("Failed to load SSF \"%s\" (object \"%s\")", ssfFile.c_str(), _tag.c_str()); } }
// "Elfland: The Woods" -> "The Woods" Common::UString Area::createDisplayName(const Common::UString &name) { for (Common::UString::iterator it = name.begin(); it != name.end(); ++it) { if (*it == ':') { if (++it == name.end()) break; if (*it == ' ') if (++it == name.end()) break; return Common::UString(it, name.end()); } } return name; }
void Creature::equipItem(Common::UString tag, InventorySlot slot, CreatureInfo &invOwner, bool updateModel) { if (_info.isInventorySlotEquipped(slot)) { Common::UString equippedItem = _info.getEquippedItem(slot); _info.unequipInventorySlot(slot); invOwner.addInventoryItem(equippedItem); _equipment.erase(slot); } if (!tag.empty() && addItemToEquipment(tag, slot)) { invOwner.removeInventoryItem(tag); _info.equipItem(tag, slot); } if (!updateModel) return; switch (slot) { case kInventorySlotBody: loadEquippedModel(); break; case kInventorySlotLeftWeapon: case kInventorySlotRightWeapon: attachWeaponModel(slot); break; default: break; } }
void Creature::loadPortrait(const Aurora::GFF3Struct &gff) { uint32 portraitID = gff.getUint("PortraitId"); if (portraitID != 0) { const Aurora::TwoDAFile &twoda = TwoDAReg.get2DA("portraits"); Common::UString portrait = twoda.getRow(portraitID).getString("BaseResRef"); if (!portrait.empty()) { if (portrait.beginsWith("po_")) _portrait = portrait; else _portrait = "po_" + portrait; } } _portrait = gff.getString("Portrait", _portrait); }
static bool setOption(Common::UString &key, const Common::UString &value) { if (key.equalsIgnoreCase("config")) { ConfigMan.setConfigFile(value); if (!ConfigMan.load()) { if (!ConfigMan.fileExists()) warning("No such config file \"%s\"", value.c_str()); return false; } key.clear(); return true; } ConfigMan.setCommandlineKey(key, value); key.clear(); return true; }
void NWNEngine::getCharacters(std::vector<Common::UString> &characters, bool local) { characters.clear(); Common::UString pcDir = ConfigMan.getString(local ? "NWN_localPCDir" : "NWN_serverPCDir"); if (pcDir.empty()) return; Common::FileList chars; chars.addDirectory(pcDir); for (Common::FileList::const_iterator c = chars.begin(); c != chars.end(); ++c) { if (!Common::FilePath::getExtension(*c).equalsIgnoreCase(".bic")) continue; characters.push_back(Common::FilePath::getStem(*c)); } }
void Door::load(const Aurora::GFF3Struct &door) { Common::UString temp = door.getString("TemplateResRef"); Aurora::GFF3File *utd = 0; if (!temp.empty()) { try { utd = new Aurora::GFF3File(temp, Aurora::kFileTypeUTD, MKTAG('U', 'T', 'D', ' ')); } catch (...) { } } Situated::load(door, utd ? &utd->getTopLevel() : 0); delete utd; setModelState(); }
Model_KotOR::ParserContext::ParserContext(const Common::UString &name, const Common::UString &t, bool k2) : mdl(0), mdx(0), state(0), texture(t), kotor2(k2) { try { if (!(mdl = ResMan.getResource(name, ::Aurora::kFileTypeMDL))) throw Common::Exception("No such MDL \"%s\"", name.c_str()); if (!(mdx = ResMan.getResource(name, ::Aurora::kFileTypeMDX))) throw Common::Exception("No such MDX \"%s\"", name.c_str()); } catch (...) { delete mdl; delete mdx; throw; } }