Cell names localization fix

actorid
lazydev 12 years ago
parent 1cf019a007
commit 74ae479780

@ -262,7 +262,7 @@ void printRaw(ESM::ESMReader &esm)
int load(Arguments& info) int load(Arguments& info)
{ {
ESM::ESMReader& esm = info.reader; ESM::ESMReader& esm = info.reader;
esm.setEncoding(info.encoding); esm.setEncoding(ToUTF8::CalculateEncoding(info.encoding));
std::string filename = info.filename; std::string filename = info.filename;
std::cout << "Loading file: " << filename << std::endl; std::cout << "Loading file: " << filename << std::endl;

@ -272,7 +272,7 @@ void DataFilesModel::addMasters(const QString &path)
foreach (const QString &path, dir.entryList()) { foreach (const QString &path, dir.entryList()) {
try { try {
ESM::ESMReader fileReader; ESM::ESMReader fileReader;
fileReader.setEncoding(mEncoding.toStdString()); fileReader.setEncoding(ToUTF8::CalculateEncoding(mEncoding.toStdString()));
fileReader.open(dir.absoluteFilePath(path).toStdString()); fileReader.open(dir.absoluteFilePath(path).toStdString());
ESM::ESMReader::MasterList mlist = fileReader.getMasters(); ESM::ESMReader::MasterList mlist = fileReader.getMasters();
@ -335,7 +335,7 @@ void DataFilesModel::addPlugins(const QString &path)
try { try {
ESM::ESMReader fileReader; ESM::ESMReader fileReader;
fileReader.setEncoding(mEncoding.toStdString()); fileReader.setEncoding(ToUTF8::CalculateEncoding(mEncoding.toStdString()));
fileReader.open(dir.absoluteFilePath(path).toStdString()); fileReader.open(dir.absoluteFilePath(path).toStdString());
ESM::ESMReader::MasterList mlist = fileReader.getMasters(); ESM::ESMReader::MasterList mlist = fileReader.getMasters();

@ -8,6 +8,7 @@
#include <components/bsa/bsa_archive.hpp> #include <components/bsa/bsa_archive.hpp>
#include <components/files/configurationmanager.hpp> #include <components/files/configurationmanager.hpp>
#include <components/translation_data/translation_data.hpp>
#include <components/nifoverrides/nifoverrides.hpp> #include <components/nifoverrides/nifoverrides.hpp>
#include <components/nifbullet/bullet_nif_loader.hpp> #include <components/nifbullet/bullet_nif_loader.hpp>
@ -334,12 +335,16 @@ void OMW::Engine::go()
mEnvironment.setWorld (new MWWorld::World (*mOgre, mFileCollections, mMaster, mEnvironment.setWorld (new MWWorld::World (*mOgre, mFileCollections, mMaster,
mResDir, mCfgMgr.getCachePath(), mNewGame, mEncoding, mFallbackMap)); mResDir, mCfgMgr.getCachePath(), mNewGame, mEncoding, mFallbackMap));
//Load translation data
std::unique_ptr<TranslationData::Storage> translationDataStorage(new TranslationData::Storage(mEncoding));
translationDataStorage->loadTranslationData(mFileCollections, mMaster);
// Create window manager - this manages all the MW-specific GUI windows // Create window manager - this manages all the MW-specific GUI windows
MWScript::registerExtensions (mExtensions); MWScript::registerExtensions (mExtensions);
mEnvironment.setWindowManager (new MWGui::WindowManager( mEnvironment.setWindowManager (new MWGui::WindowManager(
mExtensions, mFpsLevel, mNewGame, mOgre, mCfgMgr.getLogPath().string() + std::string("/"), mExtensions, mFpsLevel, mNewGame, mOgre, mCfgMgr.getLogPath().string() + std::string("/"),
mCfgMgr.getCachePath ().string(), mScriptConsoleMode)); mCfgMgr.getCachePath ().string(), mScriptConsoleMode, translationDataStorage.release()));
// Create sound system // Create sound system
mEnvironment.setSoundManager (new MWSound::SoundManager(mUseSound)); mEnvironment.setSoundManager (new MWSound::SoundManager(mUseSound));
@ -487,7 +492,7 @@ void OMW::Engine::showFPS(int level)
mFpsLevel = level; mFpsLevel = level;
} }
void OMW::Engine::setEncoding(const std::string& encoding) void OMW::Engine::setEncoding(const ToUTF8::FromType& encoding)
{ {
mEncoding = encoding; mEncoding = encoding;
} }

@ -59,7 +59,7 @@ namespace OMW
class Engine : private Ogre::FrameListener class Engine : private Ogre::FrameListener
{ {
MWBase::Environment mEnvironment; MWBase::Environment mEnvironment;
std::string mEncoding; ToUTF8::FromType mEncoding;
Files::PathContainer mDataDirs; Files::PathContainer mDataDirs;
boost::filesystem::path mResDir; boost::filesystem::path mResDir;
OEngine::Render::OgreRenderer *mOgre; OEngine::Render::OgreRenderer *mOgre;
@ -154,7 +154,7 @@ namespace OMW
void setCompileAll (bool all); void setCompileAll (bool all);
/// Font encoding /// Font encoding
void setEncoding(const std::string& encoding); void setEncoding(const ToUTF8::FromType& encoding);
void setAnimationVerbose(bool animverbose); void setAnimationVerbose(bool animverbose);

@ -181,21 +181,8 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
// Font encoding settings // Font encoding settings
std::string encoding(variables["encoding"].as<std::string>()); std::string encoding(variables["encoding"].as<std::string>());
if (encoding == "win1250") std::cout << ToUTF8::EncodingUsingMessage(encoding) << std::endl;
{ engine.setEncoding(ToUTF8::CalculateEncoding(encoding));
std::cout << "Using Central and Eastern European font encoding." << std::endl;
engine.setEncoding(encoding);
}
else if (encoding == "win1251")
{
std::cout << "Using Cyrillic font encoding." << std::endl;
engine.setEncoding(encoding);
}
else
{
std::cout << "Using default (English) font encoding." << std::endl;
engine.setEncoding("win1252");
}
// directory settings // directory settings
engine.enableFSStrict(variables["fs-strict"].as<bool>()); engine.enableFSStrict(variables["fs-strict"].as<bool>());

@ -204,21 +204,40 @@ namespace MWClass
std::string text; std::string text;
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
if (ref->mRef.mTeleport) if (ref->mRef.mTeleport)
{ {
text += "\n#{sTo}";
text += "\n" + getDestination(*ref);
}
if (ref->mRef.mLockLevel > 0)
text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->mRef.mLockLevel);
if (ref->mRef.mTrap != "")
text += "\n#{sTrapped}";
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
info.text = text;
return info;
}
std::string Door::getDestination (const MWWorld::LiveCellRef<ESM::Door>& door)
{
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
std::string dest; std::string dest;
if (ref->mRef.mDestCell != "") if (door.mRef.mDestCell != "")
{ {
// door leads to an interior, use interior name as tooltip // door leads to an interior, use interior name as tooltip
dest = ref->mRef.mDestCell; dest = door.mRef.mDestCell;
} }
else else
{ {
// door leads to exterior, use cell name (if any), otherwise translated region name // door leads to exterior, use cell name (if any), otherwise translated region name
int x,y; int x,y;
MWBase::Environment::get().getWorld()->positionToIndex (ref->mRef.mDoorDest.pos[0], ref->mRef.mDoorDest.pos[1], x, y); MWBase::Environment::get().getWorld()->positionToIndex (door.mRef.mDoorDest.pos[0], door.mRef.mDoorDest.pos[1], x, y);
const ESM::Cell* cell = store.get<ESM::Cell>().find(x,y); const ESM::Cell* cell = store.get<ESM::Cell>().find(x,y);
if (cell->mName != "") if (cell->mName != "")
dest = cell->mName; dest = cell->mName;
@ -226,24 +245,13 @@ namespace MWClass
{ {
const ESM::Region* region = const ESM::Region* region =
store.get<ESM::Region>().find(cell->mRegion); store.get<ESM::Region>().find(cell->mRegion);
dest = region->mName;
//name as is, not a token
return region->mName;
} }
} }
text += "\n#{sTo}";
text += "\n"+dest;
}
if (ref->mRef.mLockLevel > 0) return "#{sCell=" + dest + "}";
text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->mRef.mLockLevel);
if (ref->mRef.mTrap != "")
text += "\n#{sTrapped}";
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
info.text = text;
return info;
} }
MWWorld::Ptr MWWorld::Ptr

@ -31,6 +31,9 @@ namespace MWClass
virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const; virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const;
///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip.
static std::string getDestination (const MWWorld::LiveCellRef<ESM::Door>& door);
///< @return destination cell name or token
virtual void lock (const MWWorld::Ptr& ptr, int lockLevel) const; virtual void lock (const MWWorld::Ptr& ptr, int lockLevel) const;
///< Lock object ///< Lock object

@ -319,7 +319,7 @@ void HUD::setCellName(const std::string& cellName)
mCellNameTimer = 5.0f; mCellNameTimer = 5.0f;
mCellName = cellName; mCellName = cellName;
mCellNameBox->setCaption(mCellName); mCellNameBox->setCaptionWithReplacing("#{sCell=" + mCellName + "}");
mCellNameBox->setVisible(mMapVisible); mCellNameBox->setVisible(mMapVisible);
} }
} }

@ -299,7 +299,7 @@ MapWindow::~MapWindow()
void MapWindow::setCellName(const std::string& cellName) void MapWindow::setCellName(const std::string& cellName)
{ {
setTitle(cellName); setTitle("#{sCell=" + cellName + "}");
} }
void MapWindow::addVisitedLocation(const std::string& name, int x, int y) void MapWindow::addVisitedLocation(const std::string& name, int x, int y)

@ -55,7 +55,8 @@ using namespace MWGui;
WindowManager::WindowManager( WindowManager::WindowManager(
const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre,
const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts) const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts,
TranslationData::Storage* pTranslationDataStorage)
: mGuiManager(NULL) : mGuiManager(NULL)
, mHud(NULL) , mHud(NULL)
, mMap(NULL) , mMap(NULL)
@ -104,6 +105,7 @@ WindowManager::WindowManager(
, mCrosshairEnabled(Settings::Manager::getBool ("crosshair", "HUD")) , mCrosshairEnabled(Settings::Manager::getBool ("crosshair", "HUD"))
, mSubtitlesEnabled(Settings::Manager::getBool ("subtitles", "GUI")) , mSubtitlesEnabled(Settings::Manager::getBool ("subtitles", "GUI"))
, mHudEnabled(true) , mHudEnabled(true)
, mTranslationDataStorage(pTranslationDataStorage)
{ {
// Set up the GUI system // Set up the GUI system
@ -612,7 +614,7 @@ void WindowManager::changeCell(MWWorld::Ptr::CellStore* cell)
if (cell->mCell->mName != "") if (cell->mCell->mName != "")
{ {
name = cell->mCell->mName; name = cell->mCell->mName;
mMap->addVisitedLocation (name, cell->mCell->getGridX (), cell->mCell->getGridY ()); mMap->addVisitedLocation ("#{sCell=" + name + "}", cell->mCell->getGridX (), cell->mCell->getGridY ());
} }
else else
{ {
@ -721,14 +723,26 @@ void WindowManager::setDragDrop(bool dragDrop)
} }
void WindowManager::onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _result) void WindowManager::onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _result)
{
std::string tag(_tag);
std::string tokenToFind = "sCell=";
size_t tokenLength = tokenToFind.length();
if (tag.substr(0, tokenLength) == tokenToFind)
{
_result = mTranslationDataStorage->translateCellName(tag.substr(tokenLength));
}
else
{ {
const ESM::GameSetting *setting = const ESM::GameSetting *setting =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(_tag); MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(tag);
if (setting && setting->mType == ESM::VT_String) if (setting && setting->mType == ESM::VT_String)
_result = setting->getString(); _result = setting->getString();
else else
_result = _tag; _result = tag;
}
} }
void WindowManager::processChangedSettings(const Settings::CategorySettingVector& changed) void WindowManager::processChangedSettings(const Settings::CategorySettingVector& changed)

@ -14,6 +14,7 @@
#include <string> #include <string>
#include <components/esm/loadclas.hpp> #include <components/esm/loadclas.hpp>
#include <components/translation_data/translation_data.hpp>
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
@ -76,7 +77,8 @@ namespace MWGui
WindowManager(const Compiler::Extensions& extensions, int fpsLevel, bool newGame, WindowManager(const Compiler::Extensions& extensions, int fpsLevel, bool newGame,
OEngine::Render::OgreRenderer *mOgre, const std::string& logpath, OEngine::Render::OgreRenderer *mOgre, const std::string& logpath,
const std::string& cacheDir, bool consoleOnlyScripts); const std::string& cacheDir, bool consoleOnlyScripts,
TranslationData::Storage* pTranslationDataStorage);
virtual ~WindowManager(); virtual ~WindowManager();
/** /**
@ -250,6 +252,7 @@ namespace MWGui
SpellCreationDialog* mSpellCreationDialog; SpellCreationDialog* mSpellCreationDialog;
EnchantingDialog* mEnchantingDialog; EnchantingDialog* mEnchantingDialog;
TrainingWindow* mTrainingWindow; TrainingWindow* mTrainingWindow;
std::unique_ptr<TranslationData::Storage> mTranslationDataStorage;
CharacterCreation* mCharGen; CharacterCreation* mCharGen;

@ -179,7 +179,7 @@ namespace MWWorld
template <> template <>
inline const ESM::NPC *ESMStore::insert<ESM::NPC>(const ESM::NPC &npc) { inline const ESM::NPC *ESMStore::insert<ESM::NPC>(const ESM::NPC &npc) {
if (StringUtils::ciEqual(npc.mId, "player")) { if (Misc::StringUtils::ciEqual(npc.mId, "player")) {
return mNpcs.insert(npc); return mNpcs.insert(npc);
} else if (mNpcs.search(npc.mId) != 0) { } else if (mNpcs.search(npc.mId) != 0) {
std::ostringstream msg; std::ostringstream msg;

@ -1,62 +1,12 @@
#ifndef OPENMW_MWWORLD_RECORDCMP_H #ifndef OPENMW_MWWORLD_RECORDCMP_H
#define OPENMW_MWWORLD_RECORDCMP_H #define OPENMW_MWWORLD_RECORDCMP_H
#include <string>
#include <cctype> #include <cctype>
#include <algorithm>
#include <components/esm/records.hpp> #include <components/esm/records.hpp>
namespace MWWorld namespace MWWorld
{ {
/// \todo move this to another location
class StringUtils
{
struct ci
{
bool operator()(int x, int y) const {
return std::tolower(x) < std::tolower(y);
}
};
public:
static bool ciLess(const std::string &x, const std::string &y) {
return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end(), ci());
}
static bool ciEqual(const std::string &x, const std::string &y) {
if (x.size() != y.size()) {
return false;
}
std::string::const_iterator xit = x.begin();
std::string::const_iterator yit = y.begin();
for (; xit != x.end(); ++xit, ++yit) {
if (std::tolower(*xit) != std::tolower(*yit)) {
return false;
}
}
return true;
}
/// Transforms input string to lower case w/o copy
static std::string &toLower(std::string &inout) {
std::transform(
inout.begin(),
inout.end(),
inout.begin(),
(int (*)(int)) std::tolower
);
return inout;
}
/// Returns lower case copy of input string
static std::string lowerCase(const std::string &in)
{
std::string out = in;
return toLower(out);
}
};
struct RecordCmp struct RecordCmp
{ {
template <class T> template <class T>
@ -67,17 +17,17 @@ namespace MWWorld
template <> template <>
inline bool RecordCmp::operator()<ESM::Dialogue>(const ESM::Dialogue &x, const ESM::Dialogue &y) const { inline bool RecordCmp::operator()<ESM::Dialogue>(const ESM::Dialogue &x, const ESM::Dialogue &y) const {
return StringUtils::ciLess(x.mId, y.mId); return Misc::StringUtils::ciLess(x.mId, y.mId);
} }
template <> template <>
inline bool RecordCmp::operator()<ESM::Cell>(const ESM::Cell &x, const ESM::Cell &y) const { inline bool RecordCmp::operator()<ESM::Cell>(const ESM::Cell &x, const ESM::Cell &y) const {
return StringUtils::ciLess(x.mName, y.mName); return Misc::StringUtils::ciLess(x.mName, y.mName);
} }
template <> template <>
inline bool RecordCmp::operator()<ESM::Pathgrid>(const ESM::Pathgrid &x, const ESM::Pathgrid &y) const { inline bool RecordCmp::operator()<ESM::Pathgrid>(const ESM::Pathgrid &x, const ESM::Pathgrid &y) const {
return StringUtils::ciLess(x.mCell, y.mCell); return Misc::StringUtils::ciLess(x.mCell, y.mCell);
} }
} // end namespace } // end namespace

@ -105,12 +105,12 @@ namespace MWWorld
const T *search(const std::string &id) const { const T *search(const std::string &id) const {
T item; T item;
item.mId = StringUtils::lowerCase(id); item.mId = Misc::StringUtils::lowerCase(id);
typename std::vector<T>::const_iterator it = typename std::vector<T>::const_iterator it =
std::lower_bound(mStatic.begin(), mStatic.end(), item, RecordCmp()); std::lower_bound(mStatic.begin(), mStatic.end(), item, RecordCmp());
if (it != mStatic.end() && StringUtils::ciEqual(it->mId, id)) { if (it != mStatic.end() && Misc::StringUtils::ciEqual(it->mId, id)) {
return &(*it); return &(*it);
} }
@ -134,7 +134,7 @@ namespace MWWorld
void load(ESM::ESMReader &esm, const std::string &id) { void load(ESM::ESMReader &esm, const std::string &id) {
mStatic.push_back(T()); mStatic.push_back(T());
mStatic.back().mId = StringUtils::lowerCase(id); mStatic.back().mId = Misc::StringUtils::lowerCase(id);
mStatic.back().load(esm); mStatic.back().load(esm);
} }
@ -169,7 +169,7 @@ namespace MWWorld
} }
T *insert(const T &item) { T *insert(const T &item) {
std::string id = StringUtils::lowerCase(item.mId); std::string id = Misc::StringUtils::lowerCase(item.mId);
std::pair<typename Dynamic::iterator, bool> result = std::pair<typename Dynamic::iterator, bool> result =
mDynamic.insert(std::pair<std::string, T>(id, item)); mDynamic.insert(std::pair<std::string, T>(id, item));
T *ptr = &result.first->second; T *ptr = &result.first->second;
@ -182,7 +182,7 @@ namespace MWWorld
} }
bool erase(const std::string &id) { bool erase(const std::string &id) {
std::string key = StringUtils::lowerCase(id); std::string key = Misc::StringUtils::lowerCase(id);
typename Dynamic::iterator it = mDynamic.find(key); typename Dynamic::iterator it = mDynamic.find(key);
if (it == mDynamic.end()) { if (it == mDynamic.end()) {
return false; return false;
@ -213,7 +213,7 @@ namespace MWWorld
inline void Store<ESM::Script>::load(ESM::ESMReader &esm, const std::string &id) { inline void Store<ESM::Script>::load(ESM::ESMReader &esm, const std::string &id) {
mStatic.push_back(ESM::Script()); mStatic.push_back(ESM::Script());
mStatic.back().load(esm); mStatic.back().load(esm);
StringUtils::toLower(mStatic.back().mId); Misc::StringUtils::toLower(mStatic.back().mId);
} }
template <> template <>
@ -385,12 +385,12 @@ namespace MWWorld
const ESM::Cell *search(const std::string &id) const { const ESM::Cell *search(const std::string &id) const {
ESM::Cell cell; ESM::Cell cell;
cell.mName = StringUtils::lowerCase(id); cell.mName = Misc::StringUtils::lowerCase(id);
std::vector<ESM::Cell>::const_iterator it = std::vector<ESM::Cell>::const_iterator it =
std::lower_bound(mInt.begin(), mInt.end(), cell, RecordCmp()); std::lower_bound(mInt.begin(), mInt.end(), cell, RecordCmp());
if (it != mInt.end() && StringUtils::ciEqual(it->mName, id)) { if (it != mInt.end() && Misc::StringUtils::ciEqual(it->mName, id)) {
return &(*it); return &(*it);
} }
@ -490,7 +490,7 @@ namespace MWWorld
const ESM::Cell *searchExtByName(const std::string &id) const { const ESM::Cell *searchExtByName(const std::string &id) const {
std::vector<ESM::Cell *>::const_iterator it = mSharedExt.begin(); std::vector<ESM::Cell *>::const_iterator it = mSharedExt.begin();
for (; it != mSharedExt.end(); ++it) { for (; it != mSharedExt.end(); ++it) {
if (StringUtils::ciEqual((*it)->mName, id)) { if (Misc::StringUtils::ciEqual((*it)->mName, id)) {
return *it; return *it;
} }
} }
@ -501,7 +501,7 @@ namespace MWWorld
const ESM::Cell *searchExtByRegion(const std::string &id) const { const ESM::Cell *searchExtByRegion(const std::string &id) const {
std::vector<ESM::Cell *>::const_iterator it = mSharedExt.begin(); std::vector<ESM::Cell *>::const_iterator it = mSharedExt.begin();
for (; it != mSharedExt.end(); ++it) { for (; it != mSharedExt.end(); ++it) {
if (StringUtils::ciEqual((*it)->mRegion, id)) { if (Misc::StringUtils::ciEqual((*it)->mRegion, id)) {
return *it; return *it;
} }
} }
@ -541,7 +541,7 @@ namespace MWWorld
ptr = &result.first->second; ptr = &result.first->second;
mSharedExt.push_back(ptr); mSharedExt.push_back(ptr);
} else { } else {
std::string key = StringUtils::lowerCase(cell.mName); std::string key = Misc::StringUtils::lowerCase(cell.mName);
// duplicate insertions are avoided by search(ESM::Cell &) // duplicate insertions are avoided by search(ESM::Cell &)
std::pair<DynamicInt::iterator, bool> result = std::pair<DynamicInt::iterator, bool> result =
@ -561,7 +561,7 @@ namespace MWWorld
} }
bool erase(const std::string &id) { bool erase(const std::string &id) {
std::string key = StringUtils::lowerCase(id); std::string key = Misc::StringUtils::lowerCase(id);
DynamicInt::iterator it = mDynamicInt.find(key); DynamicInt::iterator it = mDynamicInt.find(key);
if (it == mDynamicInt.end()) { if (it == mDynamicInt.end()) {
@ -691,7 +691,7 @@ namespace MWWorld
pg.mCell = name; pg.mCell = name;
iterator it = std::lower_bound(mIntBegin, mIntEnd, pg, RecordCmp()); iterator it = std::lower_bound(mIntBegin, mIntEnd, pg, RecordCmp());
if (it != mIntEnd && StringUtils::ciEqual(it->mCell, name)) { if (it != mIntEnd && Misc::StringUtils::ciEqual(it->mCell, name)) {
return &(*it); return &(*it);
} }
return 0; return 0;

@ -11,6 +11,8 @@
#include "../mwrender/sky.hpp" #include "../mwrender/sky.hpp"
#include "../mwrender/player.hpp" #include "../mwrender/player.hpp"
#include "../mwclass/door.hpp"
#include "player.hpp" #include "player.hpp"
#include "manualref.hpp" #include "manualref.hpp"
#include "cellfunctors.hpp" #include "cellfunctors.hpp"
@ -168,7 +170,7 @@ namespace MWWorld
World::World (OEngine::Render::OgreRenderer& renderer, World::World (OEngine::Render::OgreRenderer& renderer,
const Files::Collections& fileCollections, const Files::Collections& fileCollections,
const std::string& master, const boost::filesystem::path& resDir, const boost::filesystem::path& cacheDir, bool newGame, const std::string& master, const boost::filesystem::path& resDir, const boost::filesystem::path& cacheDir, bool newGame,
const std::string& encoding, std::map<std::string,std::string> fallbackMap) const ToUTF8::FromType& encoding, std::map<std::string,std::string> fallbackMap)
: mPlayer (0), mLocalScripts (mStore), mGlobalVariables (0), : mPlayer (0), mLocalScripts (mStore), mGlobalVariables (0),
mSky (true), mCells (mStore, mEsm), mSky (true), mCells (mStore, mEsm),
mNumFacing(0) mNumFacing(0)
@ -237,7 +239,7 @@ namespace MWWorld
MWWorld::Store<ESM::Region>::iterator it = regions.begin(); MWWorld::Store<ESM::Region>::iterator it = regions.begin();
for (; it != regions.end(); ++it) for (; it != regions.end(); ++it)
{ {
if (MWWorld::StringUtils::ciEqual(cellName, it->mName)) if (Misc::StringUtils::ciEqual(cellName, it->mName))
{ {
return mStore.get<ESM::Cell>().searchExtByRegion(it->mId); return mStore.get<ESM::Cell>().searchExtByRegion(it->mId);
} }
@ -805,7 +807,7 @@ namespace MWWorld
{ {
bool update = false; bool update = false;
if (StringUtils::ciEqual(record.mId, "player")) if (Misc::StringUtils::ciEqual(record.mId, "player"))
{ {
static const char *sRaces[] = static const char *sRaces[] =
{ {
@ -816,7 +818,7 @@ namespace MWWorld
int i=0; int i=0;
for (; sRaces[i]; ++i) for (; sRaces[i]; ++i)
if (StringUtils::ciEqual (sRaces[i], record.mRace)) if (Misc::StringUtils::ciEqual (sRaces[i], record.mRace))
break; break;
mGlobalVariables->setInt ("pcrace", sRaces[i] ? i+1 : 0); mGlobalVariables->setInt ("pcrace", sRaces[i] ? i+1 : 0);
@ -825,9 +827,9 @@ namespace MWWorld
mPlayer->getPlayer().get<ESM::NPC>()->mBase; mPlayer->getPlayer().get<ESM::NPC>()->mBase;
update = record.isMale() != player->isMale() || update = record.isMale() != player->isMale() ||
!StringUtils::ciEqual(record.mRace, player->mRace) || !Misc::StringUtils::ciEqual(record.mRace, player->mRace) ||
!StringUtils::ciEqual(record.mHead, player->mHead) || !Misc::StringUtils::ciEqual(record.mHead, player->mHead) ||
!StringUtils::ciEqual(record.mHair, player->mHair); !Misc::StringUtils::ciEqual(record.mHair, player->mHair);
} }
const ESM::NPC *ret = mStore.insert(record); const ESM::NPC *ret = mStore.insert(record);
if (update) { if (update) {
@ -1080,28 +1082,7 @@ namespace MWWorld
if (ref.mRef.mTeleport) if (ref.mRef.mTeleport)
{ {
World::DoorMarker newMarker; World::DoorMarker newMarker;
newMarker.name = MWClass::Door::getDestination(ref);
std::string dest;
if (ref.mRef.mDestCell != "")
{
// door leads to an interior, use interior name
dest = ref.mRef.mDestCell;
}
else
{
// door leads to exterior, use cell name (if any), otherwise translated region name
int x,y;
positionToIndex (ref.mRef.mDoorDest.pos[0], ref.mRef.mDoorDest.pos[1], x, y);
const ESM::Cell* cell = mStore.get<ESM::Cell>().find(x,y);
if (cell->mName != "")
dest = cell->mName;
else
{
dest = mStore.get<ESM::Region>().find(cell->mRegion)->mName;
}
}
newMarker.name = dest;
ESM::Position pos = ref.mData.getPosition (); ESM::Position pos = ref.mData.getPosition ();

@ -95,7 +95,7 @@ namespace MWWorld
World (OEngine::Render::OgreRenderer& renderer, World (OEngine::Render::OgreRenderer& renderer,
const Files::Collections& fileCollections, const Files::Collections& fileCollections,
const std::string& master, const boost::filesystem::path& resDir, const boost::filesystem::path& cacheDir, bool newGame, const std::string& master, const boost::filesystem::path& resDir, const boost::filesystem::path& cacheDir, bool newGame,
const std::string& encoding, std::map<std::string,std::string> fallbackMap); const ToUTF8::FromType& encoding, std::map<std::string,std::string> fallbackMap);
virtual ~World(); virtual ~World();

@ -62,6 +62,10 @@ add_component_dir (interpreter
miscopcodes opcodes runtime scriptopcodes spatialopcodes types miscopcodes opcodes runtime scriptopcodes spatialopcodes types
) )
add_component_dir (translation_data
translation_data
)
include_directories(${BULLET_INCLUDE_DIRS}) include_directories(${BULLET_INCLUDE_DIRS})
add_library(components STATIC ${COMPONENT_FILES}) add_library(components STATIC ${COMPONENT_FILES})

@ -347,21 +347,9 @@ void ESMReader::fail(const std::string &msg)
throw std::runtime_error(ss.str()); throw std::runtime_error(ss.str());
} }
void ESMReader::setEncoding(const std::string& encoding) void ESMReader::setEncoding(const ToUTF8::FromType& encoding)
{ {
if (encoding == "win1250") mEncoding = encoding;
{
mEncoding = ToUTF8::WINDOWS_1250;
}
else if (encoding == "win1251")
{
mEncoding = ToUTF8::WINDOWS_1251;
}
else
{
// Default Latin encoding
mEncoding = ToUTF8::WINDOWS_1252;
}
} }
} }

@ -234,7 +234,7 @@ public:
void fail(const std::string &msg); void fail(const std::string &msg);
/// Sets font encoding for ESM strings /// Sets font encoding for ESM strings
void setEncoding(const std::string& encoding); void setEncoding(const ToUTF8::FromType& encoding);
private: private:
Ogre::DataStreamPtr mEsm; Ogre::DataStreamPtr mEsm;

@ -1,8 +1,58 @@
#ifndef MISC_STRINGOPS_H #ifndef MISC_STRINGOPS_H
#define MISC_STRINGOPS_H #define MISC_STRINGOPS_H
#include <string>
#include <algorithm>
namespace Misc namespace Misc
{ {
class StringUtils
{
struct ci
{
bool operator()(int x, int y) const {
return std::tolower(x) < std::tolower(y);
}
};
public:
static bool ciLess(const std::string &x, const std::string &y) {
return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end(), ci());
}
static bool ciEqual(const std::string &x, const std::string &y) {
if (x.size() != y.size()) {
return false;
}
std::string::const_iterator xit = x.begin();
std::string::const_iterator yit = y.begin();
for (; xit != x.end(); ++xit, ++yit) {
if (std::tolower(*xit) != std::tolower(*yit)) {
return false;
}
}
return true;
}
/// Transforms input string to lower case w/o copy
static std::string &toLower(std::string &inout) {
std::transform(
inout.begin(),
inout.end(),
inout.begin(),
(int (*)(int)) std::tolower
);
return inout;
}
/// Returns lower case copy of input string
static std::string lowerCase(const std::string &in)
{
std::string out = in;
return toLower(out);
}
};
/// Returns true if str1 begins with substring str2 /// Returns true if str1 begins with substring str2
bool begins(const char* str1, const char* str2); bool begins(const char* str1, const char* str2);

@ -357,3 +357,23 @@ std::string ToUTF8::getLegacyEnc(ToUTF8::FromType to)
// Return a string // Return a string
return std::string(&output[0], outlen); return std::string(&output[0], outlen);
} }
ToUTF8::FromType ToUTF8::CalculateEncoding(const std::string& encodingName)
{
if (encodingName == "win1250")
return ToUTF8::WINDOWS_1250;
else if (encodingName == "win1251")
return ToUTF8::WINDOWS_1251;
else
return ToUTF8::WINDOWS_1252;
}
std::string ToUTF8::EncodingUsingMessage(const std::string& encodingName)
{
if (encodingName == "win1250")
return "Using Central and Eastern European font encoding.";
else if (encodingName == "win1251")
return "Using Cyrillic font encoding.";
else
return "Using default (English) font encoding.";
}

@ -22,6 +22,9 @@ namespace ToUTF8
// page. // page.
std::string getUtf8(FromType from); std::string getUtf8(FromType from);
std::string getLegacyEnc(FromType to); std::string getLegacyEnc(FromType to);
FromType CalculateEncoding(const std::string& encodingName);
std::string EncodingUsingMessage(const std::string& encodingName);
} }
#endif #endif

@ -0,0 +1,104 @@
#include "translation_data.hpp"
#include <components/misc/stringops.hpp>
#include <fstream>
namespace TranslationData
{
void Storage::loadTranslationData(const Files::Collections& dataFileCollections,
const std::string& esmFileName)
{
std::string esmNameNoExtension(Misc::StringUtils::lowerCase(esmFileName));
//changing the extension
size_t dotPos = esmNameNoExtension.rfind('.');
if (dotPos != std::string::npos)
esmNameNoExtension.resize(dotPos);
loadData(mCellNamesTranslations, esmNameNoExtension, ".cel", dataFileCollections);
loadData(mPhraseForms, esmNameNoExtension, ".top", dataFileCollections);
loadData(mTopicIDs, esmNameNoExtension, ".mrk", dataFileCollections);
}
void Storage::loadData(ContainerType& container,
const std::string& fileNameNoExtension,
const std::string& extension,
const Files::Collections& dataFileCollections)
{
std::string path;
try
{
path = dataFileCollections.getCollection(extension).getPath(fileNameNoExtension + extension).string();
}
catch(...)
{
//no file
return;
}
std::ifstream stream(path);
if (stream.is_open())
{
loadDataFromStream(container, stream);
stream.close();
}
}
void Storage::loadDataFromStream(ContainerType& container, std::istream& stream)
{
std::string line;
while (!stream.eof())
{
std::getline( stream, line );
if (!line.empty() && *line.rbegin() == '\r')
line.resize(line.size() - 1);
if (!line.empty())
{
char* buffer = ToUTF8::getBuffer(line.size() + 1);
//buffer has at least line.size() + 1 bytes, so it must be safe
strcpy(buffer, line.c_str());
line = ToUTF8::getUtf8(mEncoding);
size_t tab_pos = line.find('\t');
if (tab_pos != std::string::npos && tab_pos > 0 && tab_pos < line.size() - 1)
{
std::string key = line.substr(0, tab_pos);
std::string value = line.substr(tab_pos + 1);
if (!key.empty() && !value.empty())
container.insert(std::make_pair(key, value));
}
}
}
}
std::string Storage::translateCellName(const std::string& cellName) const
{
auto entry = mCellNamesTranslations.find(cellName);
if (entry == mCellNamesTranslations.end())
return cellName;
return entry->second;
}
std::string Storage::topicID(const std::string& phrase) const
{
std::string result;
//seeking for the standard phrase form
auto phraseFormsIterator = mPhraseForms.find(phrase);
if (phraseFormsIterator != mPhraseForms.end())
result = phraseFormsIterator->second;
else
result = phrase;
//seeking for the topic ID
auto topicIDIterator = mTopicIDs.find(result);
if (topicIDIterator != mTopicIDs.end())
result = topicIDIterator->second;
return result;
}
}

@ -0,0 +1,36 @@
#ifndef COMPONENTS_TRANSLATION_DATA_H
#define COMPONENTS_TRANSLATION_DATA_H
#include <components/to_utf8/to_utf8.hpp>
#include <components/files/collections.hpp>
namespace TranslationData
{
class Storage
{
public:
Storage(const ToUTF8::FromType& encoding) : mEncoding(encoding) {}
void loadTranslationData(const Files::Collections& dataFileCollections,
const std::string& esmFileName);
std::string translateCellName(const std::string& cellName) const;
std::string topicID(const std::string& phrase) const;
private:
typedef std::map<std::string, std::string> ContainerType;
void loadData(ContainerType& container,
const std::string& fileNameNoExtension,
const std::string& extension,
const Files::Collections& dataFileCollections);
void loadDataFromStream(ContainerType& container, std::istream& stream);
ToUTF8::FromType mEncoding;
std::map<std::string, std::string> mCellNamesTranslations, mTopicIDs, mPhraseForms;
};
}
#endif
Loading…
Cancel
Save