diff --git a/apps/openmw/mwgui/formatting.cpp b/apps/openmw/mwgui/formatting.cpp index 1dded94fea..aac5ccbbfe 100644 --- a/apps/openmw/mwgui/formatting.cpp +++ b/apps/openmw/mwgui/formatting.cpp @@ -1,6 +1,7 @@ #include "formatting.hpp" #include +#include #include "../mwscript/interpretercontext.hpp" @@ -269,15 +270,6 @@ namespace MWGui void BookTextParser::parseImage(std::string tag, bool createWidget) { int src_start = tag.find("SRC=")+5; - std::string image = tag.substr(src_start, tag.find('"', src_start)-src_start); - - // fix texture extension to .dds - if (image.size() > 4) - { - image[image.size()-3] = 'd'; - image[image.size()-2] = 'd'; - image[image.size()-1] = 's'; - } int width_start = tag.find("WIDTH=")+7; int width = boost::lexical_cast(tag.substr(width_start, tag.find('"', width_start)-width_start)); @@ -291,16 +283,8 @@ namespace MWGui MyGUI::IntCoord(0, mHeight, width, height), MyGUI::Align::Left | MyGUI::Align::Top, mParent->getName() + boost::lexical_cast(mParent->getChildCount())); - // Apparently a bug with some morrowind versions, they reference the image without the size suffix. - // So if the image isn't found, try appending the size. - if (!Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup("bookart\\"+image)) - { - std::stringstream str; - str << image.substr(0, image.rfind(".")) << "_" << width << "_" << height << image.substr(image.rfind(".")); - image = str.str(); - } - - box->setImageTexture("bookart\\" + image); + std::string image = Misc::ResourceHelpers::correctBookartPath(tag.substr(src_start, tag.find('"', src_start)-src_start), width, height); + box->setImageTexture(image); box->setProperty("NeedMouse", "false"); } diff --git a/apps/openmw/mwgui/quickkeysmenu.cpp b/apps/openmw/mwgui/quickkeysmenu.cpp index 84150c3226..12defc6319 100644 --- a/apps/openmw/mwgui/quickkeysmenu.cpp +++ b/apps/openmw/mwgui/quickkeysmenu.cpp @@ -3,6 +3,7 @@ #include #include +#include #include "../mwworld/inventorystore.hpp" #include "../mwworld/class.hpp" @@ -226,12 +227,9 @@ namespace MWGui esmStore.get().find(spell->mEffects.mList.front().mEffectID); std::string path = effect->mIcon; - int slashPos = path.find("\\"); + int slashPos = path.rfind('\\'); path.insert(slashPos+1, "b_"); - path = std::string("icons\\") + path; - int pos = path.rfind("."); - path.erase(pos); - path.append(".dds"); + path = Misc::ResourceHelpers::correctIconPath(path); button->setFrame("textures\\menu_icon_select_magic.dds", MyGUI::IntCoord(2, 2, 40, 40)); button->setIcon(path); diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index 6d91e4feb9..e9e170ae19 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -2,6 +2,8 @@ #include +#include + #include "../mwbase/windowmanager.hpp" #include "../mwbase/soundmanager.hpp" #include "../mwbase/mechanicsmanager.hpp" @@ -143,13 +145,7 @@ namespace MWGui void EditEffectDialog::setMagicEffect (const ESM::MagicEffect *effect) { - std::string icon = effect->mIcon; - icon[icon.size()-3] = 'd'; - icon[icon.size()-2] = 'd'; - icon[icon.size()-1] = 's'; - icon = "icons\\" + icon; - - mEffectImage->setImageTexture (icon); + mEffectImage->setImageTexture(Misc::ResourceHelpers::correctIconPath(effect->mIcon)); mEffectName->setCaptionWithReplacing("#{"+ESM::MagicEffect::effectIdToString (effect->mIndex)+"}"); diff --git a/apps/openmw/mwgui/spellicons.cpp b/apps/openmw/mwgui/spellicons.cpp index 1a9e418de6..dbd91ab753 100644 --- a/apps/openmw/mwgui/spellicons.cpp +++ b/apps/openmw/mwgui/spellicons.cpp @@ -5,6 +5,8 @@ #include #include +#include + #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" @@ -133,13 +135,7 @@ namespace MWGui ("ImageBox", MyGUI::IntCoord(w,2,16,16), MyGUI::Align::Default); mWidgetMap[it->first] = image; - std::string icon = effect->mIcon; - icon[icon.size()-3] = 'd'; - icon[icon.size()-2] = 'd'; - icon[icon.size()-1] = 's'; - icon = "icons\\" + icon; - - image->setImageTexture(icon); + image->setImageTexture(Misc::ResourceHelpers::correctIconPath(effect->mIcon)); std::string name = ESM::MagicEffect::effectIdToString (it->first); diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index e09ff2487f..2cd86c7b79 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -4,6 +4,8 @@ #include +#include + #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" @@ -319,20 +321,6 @@ namespace MWGui return tooltipSize; } - void ToolTips::findImageExtension(std::string& image) - { - int len = image.size(); - if (len < 4) return; - - if (!Ogre::ResourceGroupManager::getSingleton().resourceExists(Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME, image)) - { - // Change texture extension to .dds - image[len-3] = 'd'; - image[len-2] = 'd'; - image[len-1] = 's'; - } - } - MyGUI::IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info) { mDynamicToolTipBox->setVisible(true); @@ -371,8 +359,7 @@ namespace MWGui const int imageCaptionHPadding = (caption != "" ? 8 : 0); const int imageCaptionVPadding = (caption != "" ? 4 : 0); - std::string realImage = "icons\\" + image; - findImageExtension(realImage); + std::string realImage = Misc::ResourceHelpers::correctIconPath(image); MyGUI::EditBox* captionWidget = mDynamicToolTipBox->createWidget("NormalText", MyGUI::IntCoord(0, 0, 300, 300), MyGUI::Align::Left | MyGUI::Align::Top, "ToolTipCaption"); captionWidget->setProperty("Static", "true"); @@ -644,9 +631,7 @@ namespace MWGui widget->setUserString("ToolTipType", "Layout"); widget->setUserString("ToolTipLayout", "BirthSignToolTip"); - std::string image = sign->mTexture; - image.replace(image.size()-3, 3, "dds"); - widget->setUserString("ImageTexture_BirthSignImage", "textures\\" + image); + widget->setUserString("ImageTexture_BirthSignImage", Misc::ResourceHelpers::correctTexturePath(sign->mTexture)); std::string text; text += sign->mName; @@ -739,15 +724,9 @@ namespace MWGui const std::string &name = ESM::MagicEffect::effectIdToString (id); std::string icon = effect->mIcon; - - int slashPos = icon.find("\\"); + int slashPos = icon.rfind('\\'); icon.insert(slashPos+1, "b_"); - - icon[icon.size()-3] = 'd'; - icon[icon.size()-2] = 'd'; - icon[icon.size()-1] = 's'; - - icon = "icons\\" + icon; + icon = Misc::ResourceHelpers::correctIconPath(icon); std::vector schools; schools.push_back ("#{sSchoolAlteration}"); diff --git a/apps/openmw/mwgui/tooltips.hpp b/apps/openmw/mwgui/tooltips.hpp index 8b6174b876..62ac693433 100644 --- a/apps/openmw/mwgui/tooltips.hpp +++ b/apps/openmw/mwgui/tooltips.hpp @@ -84,8 +84,6 @@ namespace MWGui MWWorld::Ptr mFocusObject; - void findImageExtension(std::string& image); - MyGUI::IntSize getToolTipViaPtr (bool image=true); ///< @return requested tooltip size diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 872740d74b..414d7b217c 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -1191,13 +1192,7 @@ void Animation::addEffect(const std::string &model, int effectId, bool loop, con if (it->mLoop && loop && it->mEffectId == effectId && it->mBoneName == bonename) return; - // fix texture extension to .dds - if (texture.size() > 4) - { - texture[texture.size()-3] = 'd'; - texture[texture.size()-2] = 'd'; - texture[texture.size()-1] = 's'; - } + std::string correctedTexture = Misc::ResourceHelpers::correctTexturePath(texture); EffectParams params; params.mModelName = model; @@ -1255,7 +1250,7 @@ void Animation::addEffect(const std::string &model, int effectId, bool loop, con for (int tex=0; texgetNumTextureUnitStates(); ++tex) { Ogre::TextureUnitState* tus = pass->getTextureUnitState(tex); - tus->setTextureName("textures\\" + texture); + tus->setTextureName(correctedTexture); } } } @@ -1285,7 +1280,7 @@ void Animation::addEffect(const std::string &model, int effectId, bool loop, con for (int tex=0; texgetNumTextureUnitStates(); ++tex) { Ogre::TextureUnitState* tus = pass->getTextureUnitState(tex); - tus->setTextureName("textures\\" + texture); + tus->setTextureName(correctedTexture); } } } diff --git a/apps/openmw/mwrender/effectmanager.cpp b/apps/openmw/mwrender/effectmanager.cpp index 968be0f9e9..a48dea8d57 100644 --- a/apps/openmw/mwrender/effectmanager.cpp +++ b/apps/openmw/mwrender/effectmanager.cpp @@ -1,5 +1,7 @@ #include "effectmanager.hpp" +#include + #include #include #include @@ -21,15 +23,6 @@ void EffectManager::addEffect(const std::string &model, std::string textureOverr Ogre::SceneNode* sceneNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(worldPosition); sceneNode->setScale(scale,scale,scale); - // fix texture extension to .dds - if (textureOverride.size() > 4) - { - textureOverride[textureOverride.size()-3] = 'd'; - textureOverride[textureOverride.size()-2] = 'd'; - textureOverride[textureOverride.size()-1] = 's'; - } - - NifOgre::ObjectScenePtr scene = NifOgre::Loader::createObjects(sceneNode, model); // TODO: turn off shadow casting @@ -44,6 +37,7 @@ void EffectManager::addEffect(const std::string &model, std::string textureOverr if (!textureOverride.empty()) { + std::string correctedTexture = Misc::ResourceHelpers::correctTexturePath(textureOverride); for(size_t i = 0;i < scene->mParticles.size(); ++i) { Ogre::ParticleSystem* partSys = scene->mParticles[i]; @@ -59,7 +53,7 @@ void EffectManager::addEffect(const std::string &model, std::string textureOverr for (int tex=0; texgetNumTextureUnitStates(); ++tex) { Ogre::TextureUnitState* tus = pass->getTextureUnitState(tex); - tus->setTextureName("textures\\" + textureOverride); + tus->setTextureName(correctedTexture); } } } diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index 5b5a1594c6..229bf92e72 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -19,6 +19,7 @@ #include #include +#include #include @@ -589,13 +590,13 @@ void SkyManager::setWeather(const MWWorld::WeatherResult& weather) if (mClouds != weather.mCloudTexture) { - sh::Factory::getInstance().setTextureAlias ("cloud_texture_1", "textures\\"+weather.mCloudTexture); + sh::Factory::getInstance().setTextureAlias ("cloud_texture_1", Misc::ResourceHelpers::correctTexturePath(weather.mCloudTexture)); mClouds = weather.mCloudTexture; } if (mNextClouds != weather.mNextCloudTexture) { - sh::Factory::getInstance().setTextureAlias ("cloud_texture_2", "textures\\"+weather.mNextCloudTexture); + sh::Factory::getInstance().setTextureAlias ("cloud_texture_2", Misc::ResourceHelpers::correctTexturePath(weather.mNextCloudTexture)); mNextClouds = weather.mNextCloudTexture; } diff --git a/apps/openmw/mwrender/terrainstorage.cpp b/apps/openmw/mwrender/terrainstorage.cpp index 2558c95c59..ae8cf21188 100644 --- a/apps/openmw/mwrender/terrainstorage.cpp +++ b/apps/openmw/mwrender/terrainstorage.cpp @@ -15,6 +15,7 @@ #include "../mwworld/esmstore.hpp" #include +#include namespace MWRender { @@ -320,14 +321,13 @@ namespace MWRender std::string TerrainStorage::getTextureName(UniqueTextureId id) { if (id.first == 0) - return "_land_default.dds"; // Not sure if the default texture floatly is hardcoded? + return "textures\\_land_default.dds"; // Not sure if the default texture floatly is hardcoded? // NB: All vtex ids are +1 compared to the ltex ids const ESM::LandTexture* ltex = getLandTexture(id.first-1, id.second); - std::string texture = ltex->mTexture; //TODO this is needed due to MWs messed up texture handling - texture = texture.substr(0, texture.rfind(".")) + ".dds"; + std::string texture = Misc::ResourceHelpers::correctTexturePath(ltex->mTexture); return texture; } @@ -516,27 +516,28 @@ namespace MWRender Terrain::LayerInfo info; info.mParallax = false; info.mSpecular = false; - info.mDiffuseMap = "textures\\" + texture; + info.mDiffuseMap = texture; std::string texture_ = texture; boost::replace_last(texture_, ".", "_nh."); - if (Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup("textures\\" + texture_)) + + if (Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(texture_)) { - info.mNormalMap = "textures\\" + texture_; + info.mNormalMap = texture_; info.mParallax = true; } else { texture_ = texture; boost::replace_last(texture_, ".", "_n."); - if (Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup("textures\\" + texture_)) - info.mNormalMap = "textures\\" + texture_; + if (Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(texture_)) + info.mNormalMap = texture_; } texture_ = texture; boost::replace_last(texture_, ".", "_diffusespec."); - if (Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup("textures\\" + texture_)) + if (Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(texture_)) { - info.mDiffuseMap = "textures\\" + texture_; + info.mDiffuseMap = texture_; info.mSpecular = true; } diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index fb45cb0343..675a3e86e6 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -73,11 +73,6 @@ Rain Height Max=700 ? Rain Threshold=0.6 ? Max Raindrops=650 ? */ - - size_t offset = weather.mCloudTexture.find(".tga"); - if (offset != std::string::npos) - weather.mCloudTexture.replace(offset, weather.mCloudTexture.length() - offset, ".dds"); - weather.mIsStorm = (name == "ashstorm" || name == "blight"); mWeatherSettings[name] = weather; diff --git a/components/misc/resourcehelpers.cpp b/components/misc/resourcehelpers.cpp index e357ac189d..9eaf441ef0 100644 --- a/components/misc/resourcehelpers.cpp +++ b/components/misc/resourcehelpers.cpp @@ -2,58 +2,89 @@ #include -#include +#include -std::string Misc::ResourceHelpers::correctResourcePath(const std::string &topLevelDirectory, const std::string &filename) +bool Misc::ResourceHelpers::changeExtensionToDds(std::string &path) +{ + Ogre::String::size_type pos = path.rfind('.'); + if(pos != Ogre::String::npos && path.compare(pos, path.length() - pos, ".dds") != 0) + { + path.replace(pos, path.length(), ".dds"); + return true; + } + return false; +} + +std::string Misc::ResourceHelpers::correctResourcePath(const std::string &topLevelDirectory, const std::string &resPath) { /* Bethesda at some point converted all their BSA * textures from tga to dds for increased load speed, but all * texture file name references were kept as .tga. */ - std::string path = topLevelDirectory + '\\'; - std::string path2 = topLevelDirectory + '/'; - std::string texname = filename; - Misc::StringUtils::toLower(texname); + std::string prefix1 = topLevelDirectory + '\\'; + std::string prefix2 = topLevelDirectory + '/'; + + std::string correctedPath = resPath; + Misc::StringUtils::toLower(correctedPath); // Apparently, leading separators are allowed - while (texname.size() && (texname[0] == '/' || texname[0] == '\\')) - texname.erase(0, 1); + while (correctedPath.size() && (correctedPath[0] == '/' || correctedPath[0] == '\\')) + correctedPath.erase(0, 1); - if(texname.compare(0, path.size()-1, path.data()) != 0 && - texname.compare(0, path2.size()-1, path2.data()) != 0) - texname = path + texname; + if(correctedPath.compare(0, prefix1.size(), prefix1.data()) != 0 && + correctedPath.compare(0, prefix2.size(), prefix2.data()) != 0) + correctedPath = prefix1 + correctedPath; - Ogre::String::size_type pos = texname.rfind('.'); - if(pos != Ogre::String::npos && texname.compare(pos, texname.length() - pos, ".dds") != 0) - { - // since we know all (GOTY edition or less) textures end - // in .dds, we change the extension - texname.replace(pos, texname.length(), ".dds"); + std::string origExt = correctedPath; + // since we know all (GOTY edition or less) textures end + // in .dds, we change the extension + if (changeExtensionToDds(correctedPath)) + { // if it turns out that the above wasn't true in all cases (not for vanilla, but maybe mods) // verify, and revert if false (this call succeeds quickly, but fails slowly) - if(!Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(texname)) + if(!Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(correctedPath)) { - texname = filename; - Misc::StringUtils::toLower(texname); - if(texname.compare(0, path.size()-1, path.data()) != 0 && - texname.compare(0, path2.size()-1, path2.data()) != 0) - texname = path + texname; + return origExt; } } - return texname; + return correctedPath; } -std::string Misc::ResourceHelpers::correctTexturePath(const std::string &filename) +std::string Misc::ResourceHelpers::correctTexturePath(const std::string &resPath) { static const std::string dir = "textures"; - return correctResourcePath(dir, filename); + return correctResourcePath(dir, resPath); } -std::string Misc::ResourceHelpers::correctIconPath(const std::string &filename) +std::string Misc::ResourceHelpers::correctIconPath(const std::string &resPath) { static const std::string dir = "icons"; - return correctResourcePath(dir, filename); + return correctResourcePath(dir, resPath); +} + +std::string Misc::ResourceHelpers::correctBookartPath(const std::string &resPath) +{ + static const std::string dir = "bookart"; + std::string image = correctResourcePath(dir, resPath); + + return image; +} + +std::string Misc::ResourceHelpers::correctBookartPath(const std::string &resPath, int width, int height) +{ + std::string image = correctBookartPath(resPath); + + // Apparently a bug with some morrowind versions, they reference the image without the size suffix. + // So if the image isn't found, try appending the size. + if (!Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(image)) + { + std::stringstream str; + str << image.substr(0, image.rfind('.')) << "_" << width << "_" << height << image.substr(image.rfind('.')); + image = Misc::ResourceHelpers::correctBookartPath(str.str()); + } + + return image; } diff --git a/components/misc/resourcehelpers.hpp b/components/misc/resourcehelpers.hpp index 42702fda85..3cf0f4c279 100644 --- a/components/misc/resourcehelpers.hpp +++ b/components/misc/resourcehelpers.hpp @@ -7,9 +7,12 @@ namespace Misc { namespace ResourceHelpers { - std::string correctResourcePath(const std::string &topLevelDirectory, const std::string &filename); - std::string correctTexturePath(const std::string &filename); - std::string correctIconPath(const std::string &filename); + bool changeExtensionToDds(std::string &path); + std::string correctResourcePath(const std::string &topLevelDirectory, const std::string &resPath); + std::string correctTexturePath(const std::string &resPath); + std::string correctIconPath(const std::string &resPath); + std::string correctBookartPath(const std::string &resPath); + std::string correctBookartPath(const std::string &resPath, int width, int height); } }