diff --git a/apps/opencs/model/world/resourcetable.cpp b/apps/opencs/model/world/resourcetable.cpp
index 86de0a6a6..58e03ff6d 100644
--- a/apps/opencs/model/world/resourcetable.cpp
+++ b/apps/opencs/model/world/resourcetable.cpp
@@ -50,7 +50,7 @@ QVariant CSMWorld::ResourceTable::headerData (int section, Qt::Orientation orien
return QVariant();
if (role==ColumnBase::Role_Flags)
- return ColumnBase::Flag_Table;
+ return section==0 ? ColumnBase::Flag_Table : 0;
switch (section)
{
diff --git a/apps/opencs/view/widget/pushbutton.cpp b/apps/opencs/view/widget/pushbutton.cpp
index 1d53d2393..307ea1a75 100644
--- a/apps/opencs/view/widget/pushbutton.cpp
+++ b/apps/opencs/view/widget/pushbutton.cpp
@@ -26,6 +26,8 @@ void CSVWidget::PushButton::setExtendedToolTip()
"
(left click to activate,"
"
shift-left click to activate and keep panel open)";
+ break;
+
case Type_Toggle:
tooltip += "
(left click to ";
diff --git a/apps/openmw/mwgui/formatting.cpp b/apps/openmw/mwgui/formatting.cpp
index 1dded94fe..aac5ccbbf 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/itemwidget.cpp b/apps/openmw/mwgui/itemwidget.cpp
index 7c79f8027..3e109384b 100644
--- a/apps/openmw/mwgui/itemwidget.cpp
+++ b/apps/openmw/mwgui/itemwidget.cpp
@@ -3,6 +3,8 @@
#include
#include
+#include
+
#include "../mwworld/class.hpp"
namespace MWGui
@@ -63,15 +65,7 @@ namespace MWGui
void ItemWidget::setIcon(const MWWorld::Ptr &ptr)
{
- // image
- std::string path = std::string("icons\\");
- path += ptr.getClass().getInventoryIcon(ptr);
-
- std::string::size_type pos = path.rfind(".");
- if(pos != std::string::npos)
- path.erase(pos);
- path.append(".dds");
- setIcon(path);
+ setIcon(Misc::ResourceHelpers::correctIconPath(ptr.getClass().getInventoryIcon(ptr)));
}
diff --git a/apps/openmw/mwgui/quickkeysmenu.cpp b/apps/openmw/mwgui/quickkeysmenu.cpp
index 84150c322..12defc631 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/recharge.cpp b/apps/openmw/mwgui/recharge.cpp
index 1b994d584..c45c2566e 100644
--- a/apps/openmw/mwgui/recharge.cpp
+++ b/apps/openmw/mwgui/recharge.cpp
@@ -181,6 +181,10 @@ void Recharge::onItemClicked(MyGUI::Widget *sender)
std::string message = MWBase::Environment::get().getWorld()->getStore().get().find("sNotifyMessage51")->getString();
message = boost::str(boost::format(message) % gem.getClass().getName(gem));
MWBase::Environment::get().getWindowManager()->messageBox(message);
+
+ // special case: readd Azura's Star
+ if (Misc::StringUtils::ciEqual(gem.get()->mBase->mId, "Misc_SoulGem_Azura"))
+ player.getClass().getContainerStore(player).add("Misc_SoulGem_Azura", 1, player);
}
updateView();
diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp
index 6d91e4feb..e9e170ae1 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 1a9e418de..dbd91ab75 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 e09ff2487..2cd86c7b7 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 8b6174b87..62ac69343 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 1fa9c611d..7a5a45832 100644
--- a/apps/openmw/mwrender/animation.cpp
+++ b/apps/openmw/mwrender/animation.cpp
@@ -17,6 +17,7 @@
#include
#include
#include
+#include
#include
@@ -1207,13 +1208,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;
@@ -1271,7 +1266,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);
}
}
}
@@ -1301,7 +1296,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 968be0f9e..a48dea8d5 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 5b5a1594c..229bf92e7 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/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp
index fb45cb034..675a3e86e 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/cmake/FindOGRE.cmake b/cmake/FindOGRE.cmake
index 4a7f0f3cc..5608c528c 100644
--- a/cmake/FindOGRE.cmake
+++ b/cmake/FindOGRE.cmake
@@ -237,7 +237,7 @@ if (OGRE_STATIC)
find_package(OpenGLES2 QUIET)
find_package(ZLIB QUIET)
find_package(ZZip QUIET)
- if (UNIX AND NOT APPLE OR NOT ANDROID)
+ if (UNIX AND (NOT APPLE AND NOT ANDROID))
find_package(X11 QUIET)
find_library(XAW_LIBRARY NAMES Xaw Xaw7 PATHS ${DEP_LIB_SEARCH_DIR} ${X11_LIB_SEARCH_PATH})
if (NOT XAW_LIBRARY OR NOT X11_Xt_FOUND)
diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt
index 2ff2dc3db..fff5b1080 100644
--- a/components/CMakeLists.txt
+++ b/components/CMakeLists.txt
@@ -50,7 +50,7 @@ add_component_dir (esmterrain
)
add_component_dir (misc
- utf8stream stringops
+ utf8stream stringops resourcehelpers
)
add_component_dir (files
diff --git a/components/esm/loadscpt.cpp b/components/esm/loadscpt.cpp
index aee8628bd..2e8f31cd2 100644
--- a/components/esm/loadscpt.cpp
+++ b/components/esm/loadscpt.cpp
@@ -38,13 +38,28 @@ void Script::load(ESMReader &esm)
char* str = &tmp[0];
for (size_t i = 0; i < mVarNames.size(); i++)
{
+ // Support '\r' terminated strings like vanilla. See Bug #1324.
char *termsym = strchr(str, '\r');
if(termsym) *termsym = '\0';
mVarNames[i] = std::string(str);
str += mVarNames[i].size() + 1;
if (str - &tmp[0] > s)
- esm.fail("String table overflow");
+ {
+ // Apparently SCVR subrecord is not used and variable names are
+ // determined on the fly from the script text. Therefore don't throw
+ // an exeption, just log an error and continue.
+ std::stringstream ss;
+
+ ss << "ESM Error: " << "String table overflow";
+ ss << "\n File: " << esm.getName();
+ ss << "\n Record: " << esm.getContext().recName.toString();
+ ss << "\n Subrecord: " << "SCVR";
+ ss << "\n Offset: 0x" << std::hex << esm.getFileOffset();
+ std::cerr << ss.str() << std::endl;
+ break;
+ }
+
}
}
diff --git a/components/esmterrain/storage.cpp b/components/esmterrain/storage.cpp
index af79b27e8..585c1495d 100644
--- a/components/esmterrain/storage.cpp
+++ b/components/esmterrain/storage.cpp
@@ -11,6 +11,7 @@
#include
#include
+#include
namespace ESMTerrain
{
@@ -276,14 +277,13 @@ namespace ESMTerrain
std::string Storage::getTextureName(UniqueTextureId id)
{
if (id.first == 0)
- return "_land_default.dds"; // Not sure if the default texture really is hardcoded?
+ return "textures\\_land_default.dds"; // Not sure if the default texture really 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;
}
@@ -472,27 +472,28 @@ namespace ESMTerrain
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/components/misc/resourcehelpers.cpp b/components/misc/resourcehelpers.cpp
new file mode 100644
index 000000000..9eaf441ef
--- /dev/null
+++ b/components/misc/resourcehelpers.cpp
@@ -0,0 +1,90 @@
+#include "resourcehelpers.hpp"
+
+#include
+
+#include
+
+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 prefix1 = topLevelDirectory + '\\';
+ std::string prefix2 = topLevelDirectory + '/';
+
+ std::string correctedPath = resPath;
+ Misc::StringUtils::toLower(correctedPath);
+
+ // Apparently, leading separators are allowed
+ while (correctedPath.size() && (correctedPath[0] == '/' || correctedPath[0] == '\\'))
+ correctedPath.erase(0, 1);
+
+ if(correctedPath.compare(0, prefix1.size(), prefix1.data()) != 0 &&
+ correctedPath.compare(0, prefix2.size(), prefix2.data()) != 0)
+ correctedPath = prefix1 + correctedPath;
+
+ 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(correctedPath))
+ {
+ return origExt;
+ }
+ }
+
+ return correctedPath;
+}
+
+std::string Misc::ResourceHelpers::correctTexturePath(const std::string &resPath)
+{
+ static const std::string dir = "textures";
+ return correctResourcePath(dir, resPath);
+}
+
+std::string Misc::ResourceHelpers::correctIconPath(const std::string &resPath)
+{
+ static const std::string dir = "icons";
+ 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
new file mode 100644
index 000000000..3cf0f4c27
--- /dev/null
+++ b/components/misc/resourcehelpers.hpp
@@ -0,0 +1,19 @@
+#ifndef MISC_RESOURCEHELPERS_H
+#define MISC_RESOURCEHELPERS_H
+
+#include
+
+namespace Misc
+{
+ namespace ResourceHelpers
+ {
+ 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);
+ }
+}
+
+#endif
diff --git a/components/nifogre/material.cpp b/components/nifogre/material.cpp
index 44831c13b..5ca58da3b 100644
--- a/components/nifogre/material.cpp
+++ b/components/nifogre/material.cpp
@@ -1,7 +1,7 @@
#include "material.hpp"
#include
-#include
+#include
#include
#include
@@ -54,49 +54,6 @@ static const char *getTestMode(int mode)
return "less_equal";
}
-
-std::string NIFMaterialLoader::findTextureName(const std::string &filename)
-{
- /* 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.
- */
- static const char path[] = "textures\\";
- static const char path2[] = "textures/";
-
- std::string texname = filename;
- Misc::StringUtils::toLower(texname);
-
- // Apparently, leading separators are allowed
- while (texname.size() && (texname[0] == '/' || texname[0] == '\\'))
- texname.erase(0, 1);
-
- if(texname.compare(0, sizeof(path)-1, path) != 0 &&
- texname.compare(0, sizeof(path2)-1, path2) != 0)
- texname = path + texname;
-
- 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");
-
- // 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))
- {
- texname = filename;
- Misc::StringUtils::toLower(texname);
- if(texname.compare(0, sizeof(path)-1, path) != 0 &&
- texname.compare(0, sizeof(path2)-1, path2) != 0)
- texname = path + texname;
- }
- }
-
- return texname;
-}
-
Ogre::String NIFMaterialLoader::getMaterial(const Nif::ShapeData *shapedata,
const Ogre::String &name, const Ogre::String &group,
const Nif::NiTexturingProperty *texprop,
@@ -146,7 +103,7 @@ Ogre::String NIFMaterialLoader::getMaterial(const Nif::ShapeData *shapedata,
const Nif::NiSourceTexture *st = texprop->textures[i].texture.getPtr();
if(st->external)
- texName[i] = findTextureName(st->filename);
+ texName[i] = Misc::ResourceHelpers::correctTexturePath(st->filename);
else
warn("Found internal texture, ignoring.");
}
diff --git a/components/nifogre/material.hpp b/components/nifogre/material.hpp
index abe1982eb..fc978549e 100644
--- a/components/nifogre/material.hpp
+++ b/components/nifogre/material.hpp
@@ -38,8 +38,6 @@ class NIFMaterialLoader {
static std::map sMaterialMap;
public:
- static std::string findTextureName(const std::string &filename);
-
static Ogre::String getMaterial(const Nif::ShapeData *shapedata,
const Ogre::String &name, const Ogre::String &group,
const Nif::NiTexturingProperty *texprop,
diff --git a/components/nifogre/ogrenifloader.cpp b/components/nifogre/ogrenifloader.cpp
index 750fa8167..be362e6ac 100644
--- a/components/nifogre/ogrenifloader.cpp
+++ b/components/nifogre/ogrenifloader.cpp
@@ -46,6 +46,7 @@
#include
#include
+#include
#include "skeleton.hpp"
#include "material.hpp"
@@ -169,7 +170,7 @@ public:
const Nif::NiSourceTexture* tex = ctrl->mSources[i].getPtr();
if (!tex->external)
std::cerr << "Warning: Found internal texture, ignoring." << std::endl;
- mTextures.push_back(NIFMaterialLoader::findTextureName(tex->filename));
+ mTextures.push_back(Misc::ResourceHelpers::correctTexturePath(tex->filename));
}
}