From 42dceb641e084b04b6046ad044bd667ee57f4efa Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Wed, 6 Aug 2014 19:46:24 +0200 Subject: [PATCH 1/9] Readd Azura's Star after recharging (Fixes #1765) --- apps/openmw/mwgui/recharge.cpp | 4 ++++ 1 file changed, 4 insertions(+) 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(); From 4873c4bd31afc4d719375c6632df0cc9b89d5a54 Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Sat, 9 Aug 2014 18:58:16 +0200 Subject: [PATCH 2/9] Generalize function for texture path correction (Fixes #1779) --- apps/openmw/mwgui/itemwidget.cpp | 12 +++--------- components/nifogre/material.cpp | 26 +++++++++++++++++++------- components/nifogre/material.hpp | 2 ++ 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/apps/openmw/mwgui/itemwidget.cpp b/apps/openmw/mwgui/itemwidget.cpp index 7c79f8027..fd4a74830 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(NifOgre::NIFMaterialLoader::findIconName(ptr.getClass().getInventoryIcon(ptr))); } diff --git a/components/nifogre/material.cpp b/components/nifogre/material.cpp index 44831c13b..e216fe984 100644 --- a/components/nifogre/material.cpp +++ b/components/nifogre/material.cpp @@ -55,14 +55,14 @@ static const char *getTestMode(int mode) } -std::string NIFMaterialLoader::findTextureName(const std::string &filename) +std::string NIFMaterialLoader::findMaterialName(const std::string &topLevelDirectory, 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 path = topLevelDirectory + '\\'; + std::string path2 = topLevelDirectory + '/'; std::string texname = filename; Misc::StringUtils::toLower(texname); @@ -71,8 +71,8 @@ std::string NIFMaterialLoader::findTextureName(const std::string &filename) 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) + if(texname.compare(0, path.size()-1, path.data()) != 0 && + texname.compare(0, path2.size()-1, path2.data()) != 0) texname = path + texname; Ogre::String::size_type pos = texname.rfind('.'); @@ -88,8 +88,8 @@ std::string NIFMaterialLoader::findTextureName(const std::string &filename) { texname = filename; Misc::StringUtils::toLower(texname); - if(texname.compare(0, sizeof(path)-1, path) != 0 && - texname.compare(0, sizeof(path2)-1, path2) != 0) + if(texname.compare(0, path.size()-1, path.data()) != 0 && + texname.compare(0, path2.size()-1, path2.data()) != 0) texname = path + texname; } } @@ -97,6 +97,18 @@ std::string NIFMaterialLoader::findTextureName(const std::string &filename) return texname; } +std::string NIFMaterialLoader::findTextureName(const std::string &filename) +{ + static const std::string dir = "textures"; + return findMaterialName(dir, filename); +} + +std::string NIFMaterialLoader::findIconName(const std::string &filename) +{ + static const std::string dir = "icons"; + return findMaterialName(dir, filename); +} + Ogre::String NIFMaterialLoader::getMaterial(const Nif::ShapeData *shapedata, const Ogre::String &name, const Ogre::String &group, const Nif::NiTexturingProperty *texprop, diff --git a/components/nifogre/material.hpp b/components/nifogre/material.hpp index abe1982eb..df37ce164 100644 --- a/components/nifogre/material.hpp +++ b/components/nifogre/material.hpp @@ -38,7 +38,9 @@ class NIFMaterialLoader { static std::map sMaterialMap; public: + static std::string findMaterialName(const std::string &topLevelDirectory, const std::string &filename); static std::string findTextureName(const std::string &filename); + static std::string findIconName(const std::string &filename); static Ogre::String getMaterial(const Nif::ShapeData *shapedata, const Ogre::String &name, const Ogre::String &group, From c43bd3c3452d3537441780eff707daccc918571b Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sun, 10 Aug 2014 12:54:54 +1000 Subject: [PATCH 3/9] Continue loading esm after detecting string table overflow condition. Should resolve bug #1774. --- components/esm/loadscpt.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/components/esm/loadscpt.cpp b/components/esm/loadscpt.cpp index aee8628bd..abc05cc94 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::cout << ss.str() << std::endl; + break; + } + } } From ee3acc31a827f79ea3a7475b306c6c34ba642125 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 10 Aug 2014 10:09:45 +0200 Subject: [PATCH 4/9] minor correction to previous commit --- components/esm/loadscpt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esm/loadscpt.cpp b/components/esm/loadscpt.cpp index abc05cc94..2e8f31cd2 100644 --- a/components/esm/loadscpt.cpp +++ b/components/esm/loadscpt.cpp @@ -56,7 +56,7 @@ void Script::load(ESMReader &esm) ss << "\n Record: " << esm.getContext().recName.toString(); ss << "\n Subrecord: " << "SCVR"; ss << "\n Offset: 0x" << std::hex << esm.getFileOffset(); - std::cout << ss.str() << std::endl; + std::cerr << ss.str() << std::endl; break; } From f6b2e7d5fd1f82f551f1320f66e0e2934948712a Mon Sep 17 00:00:00 2001 From: slothlife Date: Sun, 10 Aug 2014 18:28:38 -0500 Subject: [PATCH 5/9] Fix building on Win32 --- cmake/FindOGRE.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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) From 4d403ed747fa8047fc165e07aae15eb2e5d64b77 Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Mon, 11 Aug 2014 20:04:44 +0200 Subject: [PATCH 6/9] Rename and move functions for texture path correction --- apps/openmw/mwgui/itemwidget.cpp | 4 +- components/CMakeLists.txt | 2 +- components/misc/resourcehelpers.cpp | 59 ++++++++++++++++++++++++++++ components/misc/resourcehelpers.hpp | 16 ++++++++ components/nifogre/material.cpp | 59 +--------------------------- components/nifogre/material.hpp | 4 -- components/nifogre/ogrenifloader.cpp | 3 +- 7 files changed, 82 insertions(+), 65 deletions(-) create mode 100644 components/misc/resourcehelpers.cpp create mode 100644 components/misc/resourcehelpers.hpp diff --git a/apps/openmw/mwgui/itemwidget.cpp b/apps/openmw/mwgui/itemwidget.cpp index fd4a74830..3e109384b 100644 --- a/apps/openmw/mwgui/itemwidget.cpp +++ b/apps/openmw/mwgui/itemwidget.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include "../mwworld/class.hpp" @@ -65,7 +65,7 @@ namespace MWGui void ItemWidget::setIcon(const MWWorld::Ptr &ptr) { - setIcon(NifOgre::NIFMaterialLoader::findIconName(ptr.getClass().getInventoryIcon(ptr))); + setIcon(Misc::ResourceHelpers::correctIconPath(ptr.getClass().getInventoryIcon(ptr))); } diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index f343ca8ed..21e062fc0 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -46,7 +46,7 @@ add_component_dir (esm ) add_component_dir (misc - utf8stream stringops + utf8stream stringops resourcehelpers ) add_component_dir (files diff --git a/components/misc/resourcehelpers.cpp b/components/misc/resourcehelpers.cpp new file mode 100644 index 000000000..e357ac189 --- /dev/null +++ b/components/misc/resourcehelpers.cpp @@ -0,0 +1,59 @@ +#include "resourcehelpers.hpp" + +#include + +#include + +std::string Misc::ResourceHelpers::correctResourcePath(const std::string &topLevelDirectory, 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. + */ + std::string path = topLevelDirectory + '\\'; + std::string path2 = topLevelDirectory + '/'; + + 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, path.size()-1, path.data()) != 0 && + texname.compare(0, path2.size()-1, path2.data()) != 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, path.size()-1, path.data()) != 0 && + texname.compare(0, path2.size()-1, path2.data()) != 0) + texname = path + texname; + } + } + + return texname; +} + +std::string Misc::ResourceHelpers::correctTexturePath(const std::string &filename) +{ + static const std::string dir = "textures"; + return correctResourcePath(dir, filename); +} + +std::string Misc::ResourceHelpers::correctIconPath(const std::string &filename) +{ + static const std::string dir = "icons"; + return correctResourcePath(dir, filename); +} diff --git a/components/misc/resourcehelpers.hpp b/components/misc/resourcehelpers.hpp new file mode 100644 index 000000000..42702fda8 --- /dev/null +++ b/components/misc/resourcehelpers.hpp @@ -0,0 +1,16 @@ +#ifndef MISC_RESOURCEHELPERS_H +#define MISC_RESOURCEHELPERS_H + +#include + +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); + } +} + +#endif diff --git a/components/nifogre/material.cpp b/components/nifogre/material.cpp index e216fe984..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,61 +54,6 @@ static const char *getTestMode(int mode) return "less_equal"; } - -std::string NIFMaterialLoader::findMaterialName(const std::string &topLevelDirectory, 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. - */ - std::string path = topLevelDirectory + '\\'; - std::string path2 = topLevelDirectory + '/'; - - 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, path.size()-1, path.data()) != 0 && - texname.compare(0, path2.size()-1, path2.data()) != 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, path.size()-1, path.data()) != 0 && - texname.compare(0, path2.size()-1, path2.data()) != 0) - texname = path + texname; - } - } - - return texname; -} - -std::string NIFMaterialLoader::findTextureName(const std::string &filename) -{ - static const std::string dir = "textures"; - return findMaterialName(dir, filename); -} - -std::string NIFMaterialLoader::findIconName(const std::string &filename) -{ - static const std::string dir = "icons"; - return findMaterialName(dir, filename); -} - Ogre::String NIFMaterialLoader::getMaterial(const Nif::ShapeData *shapedata, const Ogre::String &name, const Ogre::String &group, const Nif::NiTexturingProperty *texprop, @@ -158,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 df37ce164..fc978549e 100644 --- a/components/nifogre/material.hpp +++ b/components/nifogre/material.hpp @@ -38,10 +38,6 @@ class NIFMaterialLoader { static std::map sMaterialMap; public: - static std::string findMaterialName(const std::string &topLevelDirectory, const std::string &filename); - static std::string findTextureName(const std::string &filename); - static std::string findIconName(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)); } } From 98fa789904cca249628f70d2687e9ea4dede184b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 12 Aug 2014 11:07:54 +0200 Subject: [PATCH 7/9] fixed mixed-up tooltip --- apps/opencs/view/widget/pushbutton.cpp | 2 ++ 1 file changed, 2 insertions(+) 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 "; From a5ecf2e9f092b193ff46de3e16d4f0a75264ce78 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 12 Aug 2014 11:32:38 +0200 Subject: [PATCH 8/9] hide record type column in resources tables --- apps/opencs/model/world/resourcetable.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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) { From baa14511cf3cca95460c7ed7ac24dd563d97dfa6 Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Tue, 12 Aug 2014 12:18:38 +0200 Subject: [PATCH 9/9] Use ResourceHelpers to replace DDS hacks scattered throughout the code, fix prefix comparision --- apps/openmw/mwgui/formatting.cpp | 22 +----- apps/openmw/mwgui/quickkeysmenu.cpp | 8 +-- apps/openmw/mwgui/spellcreationdialog.cpp | 10 +-- apps/openmw/mwgui/spellicons.cpp | 10 +-- apps/openmw/mwgui/tooltips.cpp | 33 ++------- apps/openmw/mwgui/tooltips.hpp | 2 - apps/openmw/mwrender/animation.cpp | 13 ++-- apps/openmw/mwrender/effectmanager.cpp | 14 ++-- apps/openmw/mwrender/sky.cpp | 5 +- apps/openmw/mwrender/terrainstorage.cpp | 21 +++--- apps/openmw/mwworld/weather.cpp | 5 -- components/misc/resourcehelpers.cpp | 87 +++++++++++++++-------- components/misc/resourcehelpers.hpp | 9 ++- 13 files changed, 105 insertions(+), 134 deletions(-) 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/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/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 872740d74..414d7b217 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 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/mwrender/terrainstorage.cpp b/apps/openmw/mwrender/terrainstorage.cpp index 2558c95c5..ae8cf2118 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 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/components/misc/resourcehelpers.cpp b/components/misc/resourcehelpers.cpp index e357ac189..9eaf441ef 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 42702fda8..3cf0f4c27 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); } }