From f12d5b728ad9462a9f99c5905da9ceef8d86a1ed Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 29 Aug 2013 17:14:25 +0200 Subject: [PATCH 01/15] Ogre 1.9 compatibility changes --- apps/openmw/mwrender/videoplayer.cpp | 1 - extern/sdl4ogre/cursormanager.hpp | 5 +---- libs/openengine/bullet/BulletShapeLoader.cpp | 14 +++++++++++++ libs/openengine/bullet/BulletShapeLoader.h | 21 +++++++++++++++++--- 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwrender/videoplayer.cpp b/apps/openmw/mwrender/videoplayer.cpp index 8c557ee998..ee2b80f731 100644 --- a/apps/openmw/mwrender/videoplayer.cpp +++ b/apps/openmw/mwrender/videoplayer.cpp @@ -1037,7 +1037,6 @@ public: VideoPlayer::VideoPlayer(Ogre::SceneManager* sceneMgr, Ogre::RenderWindow* window) : mState(NULL) , mSceneMgr(sceneMgr) - , mVideoMaterial(NULL) , mRectangle(NULL) , mNode(NULL) , mAllowSkipping(false) diff --git a/extern/sdl4ogre/cursormanager.hpp b/extern/sdl4ogre/cursormanager.hpp index 1f52eca730..04106fd2f1 100644 --- a/extern/sdl4ogre/cursormanager.hpp +++ b/extern/sdl4ogre/cursormanager.hpp @@ -4,10 +4,7 @@ #include #include -namespace Ogre -{ - class TexturePtr; -} +#include namespace SFO { diff --git a/libs/openengine/bullet/BulletShapeLoader.cpp b/libs/openengine/bullet/BulletShapeLoader.cpp index 431d2b91b4..5528924a9a 100644 --- a/libs/openengine/bullet/BulletShapeLoader.cpp +++ b/libs/openengine/bullet/BulletShapeLoader.cpp @@ -104,6 +104,20 @@ BulletShapeManager::~BulletShapeManager() sThis = 0; } +#if (OGRE_VERSION >= ((1 << 16) | (9 << 8) | 0)) +BulletShapePtr BulletShapeManager::getByName(const Ogre::String& name, const Ogre::String& groupName) +{ + return getResourceByName(name, groupName).staticCast(); +} + +BulletShapePtr BulletShapeManager::create (const Ogre::String& name, const Ogre::String& group, + bool isManual, Ogre::ManualResourceLoader* loader, + const Ogre::NameValuePairList* createParams) +{ + return createResource(name,group,isManual,loader,createParams).staticCast(); +} +#endif + BulletShapePtr BulletShapeManager::load(const Ogre::String &name, const Ogre::String &group) { BulletShapePtr textf = getByName(name); diff --git a/libs/openengine/bullet/BulletShapeLoader.h b/libs/openengine/bullet/BulletShapeLoader.h index a6591010ad..98cda859db 100644 --- a/libs/openengine/bullet/BulletShapeLoader.h +++ b/libs/openengine/bullet/BulletShapeLoader.h @@ -48,6 +48,8 @@ public: /** * */ + +#if (OGRE_VERSION < ((1 << 16) | (9 << 8) | 0)) class BulletShapePtr : public Ogre::SharedPtr { public: @@ -91,9 +93,9 @@ public: return *this; } }; - - - +#else +typedef Ogre::SharedPtr BulletShapePtr; +#endif /** *Hold any BulletShape that was created by the ManualBulletShapeLoader. @@ -137,6 +139,19 @@ public: BulletShapeManager(); virtual ~BulletShapeManager(); + +#if (OGRE_VERSION >= ((1 << 16) | (9 << 8) | 0)) + /// Get a resource by name + /// @see ResourceManager::getByName + BulletShapePtr getByName(const Ogre::String& name, const Ogre::String& groupName = Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); + + /// Create a new shape + /// @see ResourceManager::createResource + BulletShapePtr create (const Ogre::String& name, const Ogre::String& group, + bool isManual = false, Ogre::ManualResourceLoader* loader = 0, + const Ogre::NameValuePairList* createParams = 0); +#endif + virtual BulletShapePtr load(const Ogre::String &name, const Ogre::String &group); static BulletShapeManager &getSingleton(); From f9dbce685a44eff094944dd16c873b13205a29d1 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 29 Aug 2013 17:07:02 -0700 Subject: [PATCH 02/15] Avoid killing AIWander and AITravel when far away This fixes the problem of certain NPCs not wandering because they happened to spawn near a cell border away from the player, which immediately "completed" the wander package. AIWander can't cause NPCs to cross cell boundaries, so there's no risk of them walking into an unloaded to. AITravel will now simply stop moving, and resume later when the cell is loaded. --- apps/openmw/mwmechanics/aitravel.cpp | 54 ++++++++++++++-------------- apps/openmw/mwmechanics/aiwander.cpp | 43 ++++------------------ 2 files changed, 35 insertions(+), 62 deletions(-) diff --git a/apps/openmw/mwmechanics/aitravel.cpp b/apps/openmw/mwmechanics/aitravel.cpp index 6b43a36f69..d47a49c702 100644 --- a/apps/openmw/mwmechanics/aitravel.cpp +++ b/apps/openmw/mwmechanics/aitravel.cpp @@ -33,46 +33,48 @@ namespace MWMechanics bool AiTravel::execute (const MWWorld::Ptr& actor) { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWBase::World *world = MWBase::Environment::get().getWorld(); ESM::Position pos = actor.getRefData().getPosition(); - bool cellChange = actor.getCell()->mCell->mData.mX != cellX || actor.getCell()->mCell->mData.mY != cellY; - const ESM::Pathgrid *pathgrid = - MWBase::Environment::get().getWorld()->getStore().get().search(*actor.getCell()->mCell); + Movement &movement = actor.getClass().getMovementSettings(actor); + const ESM::Cell *cell = actor.getCell()->mCell; - if(actor.getCell()->mCell->mData.mX != player.getCell()->mCell->mData.mX) + MWWorld::Ptr player = world->getPlayer().getPlayer(); + if(cell->mData.mX != player.getCell()->mCell->mData.mX) { - int sideX = sgn(actor.getCell()->mCell->mData.mX - player.getCell()->mCell->mData.mX); - //check if actor is near the border of an inactive cell. If so, disable aitravel. - if(sideX * (pos.pos[0] - actor.getCell()->mCell->mData.mX * ESM::Land::REAL_SIZE) > sideX * (ESM::Land::REAL_SIZE / - 2.0 - 200)) + int sideX = sgn(cell->mData.mX - player.getCell()->mCell->mData.mX); + //check if actor is near the border of an inactive cell. If so, stop walking. + if(sideX * (pos.pos[0] - cell->mData.mX*ESM::Land::REAL_SIZE) > + sideX * (ESM::Land::REAL_SIZE/2.0f - 200.0f)) { - MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; - return true; + movement.mPosition[1] = 0; + return false; } } - if(actor.getCell()->mCell->mData.mY != player.getCell()->mCell->mData.mY) + if(cell->mData.mY != player.getCell()->mCell->mData.mY) { - int sideY = sgn(actor.getCell()->mCell->mData.mY - player.getCell()->mCell->mData.mY); - //check if actor is near the border of an inactive cell. If so, disable aitravel. - if(sideY * (pos.pos[1] - actor.getCell()->mCell->mData.mY * ESM::Land::REAL_SIZE) > sideY * (ESM::Land::REAL_SIZE / - 2.0 - 200)) + int sideY = sgn(cell->mData.mY - player.getCell()->mCell->mData.mY); + //check if actor is near the border of an inactive cell. If so, stop walking. + if(sideY * (pos.pos[1] - cell->mData.mY*ESM::Land::REAL_SIZE) > + sideY * (ESM::Land::REAL_SIZE/2.0f - 200.0f)) { - MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; - return true; + movement.mPosition[1] = 0; + return false; } } + const ESM::Pathgrid *pathgrid = world->getStore().get().search(*cell); + bool cellChange = cell->mData.mX != cellX || cell->mData.mY != cellY; if(!mPathFinder.isPathConstructed() || cellChange) { - cellX = actor.getCell()->mCell->mData.mX; - cellY = actor.getCell()->mCell->mData.mY; + cellX = cell->mData.mX; + cellY = cell->mData.mY; float xCell = 0; float yCell = 0; - if (actor.getCell()->mCell->isExterior()) + if(cell->isExterior()) { - xCell = actor.getCell()->mCell->mData.mX * ESM::Land::REAL_SIZE; - yCell = actor.getCell()->mCell->mData.mY * ESM::Land::REAL_SIZE; + xCell = cell->mData.mX * ESM::Land::REAL_SIZE; + yCell = cell->mData.mY * ESM::Land::REAL_SIZE; } ESM::Pathgrid::Point dest; @@ -90,13 +92,13 @@ namespace MWMechanics if(mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1], pos.pos[2])) { - MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; + movement.mPosition[1] = 0; return true; } float zAngle = mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1]); - MWBase::Environment::get().getWorld()->rotateObject(actor, 0, 0, zAngle, false); - MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1; + world->rotateObject(actor, 0, 0, zAngle, false); + movement.mPosition[1] = 1; return false; } diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index c4f32f5dce..50191193d9 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -65,10 +65,11 @@ namespace MWMechanics bool AiWander::execute (const MWWorld::Ptr& actor) { + MWBase::World *world = MWBase::Environment::get().getWorld(); if(mDuration) { // End package if duration is complete or mid-night hits: - MWWorld::TimeStamp currentTime = MWBase::Environment::get().getWorld()->getTimeStamp(); + MWWorld::TimeStamp currentTime = world->getTimeStamp(); if(currentTime.getHour() >= mStartTime.getHour() + mDuration) { if(!mRepeat) @@ -96,8 +97,7 @@ namespace MWMechanics if(!mStoredAvailableNodes) { mStoredAvailableNodes = true; - mPathgrid = - MWBase::Environment::get().getWorld()->getStore().get().search(*actor.getCell()->mCell); + mPathgrid = world->getStore().get().search(*actor.getCell()->mCell); mCellX = actor.getCell()->mCell->mData.mX; mCellY = actor.getCell()->mCell->mData.mY; @@ -150,37 +150,8 @@ namespace MWMechanics } } - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); - bool cellChange = actor.getCell()->mCell->mData.mX != mCellX || actor.getCell()->mCell->mData.mY != mCellY; - - if(actor.getCell()->mCell->mData.mX != player.getCell()->mCell->mData.mX) - { - int sideX = sgn(actor.getCell()->mCell->mData.mX - player.getCell()->mCell->mData.mX); - // Check if actor is near the border of an inactive cell. If so, disable AiWander. - // FIXME: This *should* pause the AiWander package instead of terminating it. - if(sideX * (pos.pos[0] - actor.getCell()->mCell->mData.mX * ESM::Land::REAL_SIZE) > sideX * (ESM::Land::REAL_SIZE / - 2.0 - 200)) - { - stopWalking(actor); - return true; - } - } - - if(actor.getCell()->mCell->mData.mY != player.getCell()->mCell->mData.mY) - { - int sideY = sgn(actor.getCell()->mCell->mData.mY - player.getCell()->mCell->mData.mY); - // Check if actor is near the border of an inactive cell. If so, disable AiWander. - // FIXME: This *should* pause the AiWander package instead of terminating it. - if(sideY * (pos.pos[1] - actor.getCell()->mCell->mData.mY * ESM::Land::REAL_SIZE) > sideY * (ESM::Land::REAL_SIZE / - 2.0 - 200)) - { - stopWalking(actor); - return true; - } - } - // Don't try to move if you are in a new cell (ie: positioncell command called) but still play idles. - if(mDistance && (cellChange || (mCellX != actor.getCell()->mCell->mData.mX || mCellY != actor.getCell()->mCell->mData.mY))) + if(mDistance && (mCellX != actor.getCell()->mCell->mData.mX || mCellY != actor.getCell()->mCell->mData.mY)) mDistance = 0; if(mChooseAction) @@ -207,7 +178,7 @@ namespace MWMechanics else { // Play idle animation and recreate vanilla (broken?) behavior of resetting start time of AIWander: - MWWorld::TimeStamp currentTime = MWBase::Environment::get().getWorld()->getTimeStamp(); + MWWorld::TimeStamp currentTime = world->getTimeStamp(); mStartTime = currentTime; playIdle(actor, mPlayedIdle); mChooseAction = false; @@ -264,7 +235,7 @@ namespace MWMechanics if(mWalking) { float zAngle = mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1]); - MWBase::Environment::get().getWorld()->rotateObject(actor, 0, 0, zAngle,false); + world->rotateObject(actor, 0, 0, zAngle, false); MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1; // Unclog path nodes by allowing the NPC to be a small distance away from the center. This way two NPCs can be @@ -275,7 +246,7 @@ namespace MWMechanics actorPos[1] = actorPos[1] - mYCell; float distance = actorPos.squaredDistance(destNodePos); - if(distance < 1200 || mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1], pos.pos[2])) + if(distance < 32*32 || mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1], pos.pos[2])) { stopWalking(actor); mMoveNow = false; From 9499ac4fd59a68fba884b8f3b9e06ead18c19ba9 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 29 Aug 2013 17:32:20 -0700 Subject: [PATCH 03/15] Increase the distance for reaching a path node --- apps/openmw/mwmechanics/aiwander.cpp | 10 +--------- apps/openmw/mwmechanics/pathfinding.cpp | 2 +- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index 50191193d9..96a41883b9 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -238,15 +238,7 @@ namespace MWMechanics world->rotateObject(actor, 0, 0, zAngle, false); MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1; - // Unclog path nodes by allowing the NPC to be a small distance away from the center. This way two NPCs can be - // at the same path node at the same time and both will complete instead of endlessly walking into eachother: - Ogre::Vector3 destNodePos(mCurrentNode.mX, mCurrentNode.mY, mCurrentNode.mZ); - Ogre::Vector3 actorPos(actor.getRefData().getPosition().pos); - actorPos[0] = actorPos[0] - mXCell; - actorPos[1] = actorPos[1] - mYCell; - float distance = actorPos.squaredDistance(destNodePos); - - if(distance < 32*32 || mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1], pos.pos[2])) + if(mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1], pos.pos[2])) { stopWalking(actor); mMoveNow = false; diff --git a/apps/openmw/mwmechanics/pathfinding.cpp b/apps/openmw/mwmechanics/pathfinding.cpp index da9d52e446..7e0e1550b7 100644 --- a/apps/openmw/mwmechanics/pathfinding.cpp +++ b/apps/openmw/mwmechanics/pathfinding.cpp @@ -205,7 +205,7 @@ namespace MWMechanics return true; ESM::Pathgrid::Point nextPoint = *mPath.begin(); - if(distanceZCorrected(nextPoint, x, y, z) < 40) + if(distanceZCorrected(nextPoint, x, y, z) < 64) { mPath.pop_front(); if(mPath.empty()) From 1026e89810ca2c70f85063243d040ac4042f3f7b Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 29 Aug 2013 17:40:21 -0700 Subject: [PATCH 04/15] Don't assume TexturePtr is a class --- extern/sdl4ogre/cursormanager.hpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/extern/sdl4ogre/cursormanager.hpp b/extern/sdl4ogre/cursormanager.hpp index 1f52eca730..06de094f74 100644 --- a/extern/sdl4ogre/cursormanager.hpp +++ b/extern/sdl4ogre/cursormanager.hpp @@ -4,10 +4,7 @@ #include #include -namespace Ogre -{ - class TexturePtr; -} +#include namespace SFO { From 8f23b330d3e48d904bee3bb26378b32b9ee3b77b Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 29 Aug 2013 17:40:52 -0700 Subject: [PATCH 05/15] Remove unnecessary initialization --- apps/openmw/mwrender/videoplayer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/openmw/mwrender/videoplayer.cpp b/apps/openmw/mwrender/videoplayer.cpp index 8c557ee998..ee2b80f731 100644 --- a/apps/openmw/mwrender/videoplayer.cpp +++ b/apps/openmw/mwrender/videoplayer.cpp @@ -1037,7 +1037,6 @@ public: VideoPlayer::VideoPlayer(Ogre::SceneManager* sceneMgr, Ogre::RenderWindow* window) : mState(NULL) , mSceneMgr(sceneMgr) - , mVideoMaterial(NULL) , mRectangle(NULL) , mNode(NULL) , mAllowSkipping(false) From 82a09a988bcd0b0cd2202b7bc2bfc346234f2ea8 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 29 Aug 2013 19:17:27 -0700 Subject: [PATCH 06/15] Minor pathfinding cleanup --- apps/openmw/mwmechanics/pathfinding.cpp | 22 ++++++---------------- apps/openmw/mwmechanics/pathfinding.hpp | 13 ++++++++----- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/apps/openmw/mwmechanics/pathfinding.cpp b/apps/openmw/mwmechanics/pathfinding.cpp index 7e0e1550b7..8ef0edab83 100644 --- a/apps/openmw/mwmechanics/pathfinding.cpp +++ b/apps/openmw/mwmechanics/pathfinding.cpp @@ -147,13 +147,13 @@ namespace MWMechanics mIsPathConstructed = false; } - void PathFinder::buildPath(ESM::Pathgrid::Point startPoint, ESM::Pathgrid::Point endPoint, - const ESM::Pathgrid* pathGrid, float xCell, float yCell, bool allowShortcuts) + void PathFinder::buildPath(const ESM::Pathgrid::Point &startPoint, const ESM::Pathgrid::Point &endPoint, + const ESM::Pathgrid *pathGrid, float xCell, float yCell, bool allowShortcuts) { if(allowShortcuts) { - if(MWBase::Environment::get().getWorld()->castRay(startPoint.mX, startPoint.mY, startPoint.mZ, endPoint.mX, endPoint.mY, - endPoint.mZ)) + if(MWBase::Environment::get().getWorld()->castRay(startPoint.mX, startPoint.mY, startPoint.mZ, + endPoint.mX, endPoint.mY, endPoint.mZ)) allowShortcuts = false; } @@ -184,14 +184,14 @@ namespace MWMechanics mIsPathConstructed = false; } - float PathFinder::getZAngleToNext(float x, float y) + float PathFinder::getZAngleToNext(float x, float y) const { // This should never happen (programmers should have an if statement checking mIsPathConstructed that prevents this call // if otherwise). if(mPath.empty()) return 0; - ESM::Pathgrid::Point nextPoint = *mPath.begin(); + const ESM::Pathgrid::Point &nextPoint = *mPath.begin(); float directionX = nextPoint.mX - x; float directionY = nextPoint.mY - y; float directionResult = sqrt(directionX * directionX + directionY * directionY); @@ -217,15 +217,5 @@ namespace MWMechanics return false; } - - std::list PathFinder::getPath() - { - return mPath; - } - - bool PathFinder::isPathConstructed() - { - return mIsPathConstructed; - } } diff --git a/apps/openmw/mwmechanics/pathfinding.hpp b/apps/openmw/mwmechanics/pathfinding.hpp index 1727c650f3..35e0fa9087 100644 --- a/apps/openmw/mwmechanics/pathfinding.hpp +++ b/apps/openmw/mwmechanics/pathfinding.hpp @@ -12,15 +12,18 @@ namespace MWMechanics PathFinder(); void clearPath(); - void buildPath(ESM::Pathgrid::Point startPoint, ESM::Pathgrid::Point endPoint, - const ESM::Pathgrid* pathGrid, float xCell = 0, float yCell = 0, bool allowShortcuts = 1); + void buildPath(const ESM::Pathgrid::Point &startPoint, const ESM::Pathgrid::Point &endPoint, + const ESM::Pathgrid* pathGrid, float xCell = 0, float yCell = 0, + bool allowShortcuts = true); bool checkPathCompleted(float x, float y, float z); ///< \Returns true if the last point of the path has been reached. - float getZAngleToNext(float x, float y); + float getZAngleToNext(float x, float y) const; - std::list getPath(); - bool isPathConstructed(); + bool isPathConstructed() const + { + return mIsPathConstructed; + } private: std::list mPath; From da0b90ee45ae7655c16ee152240afb86a7e6ea7a Mon Sep 17 00:00:00 2001 From: Lukasz Gromanowski Date: Fri, 30 Aug 2013 21:51:23 +0200 Subject: [PATCH 07/15] Converted tests from components/misc into google unittests. Signed-off-by: Lukasz Gromanowski --- apps/openmw_test_suite/CMakeLists.txt | 4 +- .../components/misc/test_slicearray.cpp | 33 ++++++++ .../components/misc/test_stringops.cpp | 76 ++++++++++++++++++- apps/openmw_test_suite/openmw_test_suite.cpp | 4 +- 4 files changed, 111 insertions(+), 6 deletions(-) create mode 100644 apps/openmw_test_suite/components/misc/test_slicearray.cpp diff --git a/apps/openmw_test_suite/CMakeLists.txt b/apps/openmw_test_suite/CMakeLists.txt index cdf8bc74b0..9fe7890acc 100644 --- a/apps/openmw_test_suite/CMakeLists.txt +++ b/apps/openmw_test_suite/CMakeLists.txt @@ -11,14 +11,14 @@ if (GTEST_FOUND AND GMOCK_FOUND) include_directories(${GMOCK_INCLUDE_DIRS}) file(GLOB UNITTEST_SRC_FILES - components/misc/*.cpp + components/misc/test_*.cpp ) source_group(apps\\openmw_test_suite FILES openmw_test_suite.cpp ${UNITTEST_SRC_FILES}) add_executable(openmw_test_suite openmw_test_suite.cpp ${UNITTEST_SRC_FILES}) - target_link_libraries(openmw_test_suite ${GMOCK_BOTH_LIBRARIES} ${GTEST_BOTH_LIBRARIES}) + target_link_libraries(openmw_test_suite ${GMOCK_BOTH_LIBRARIES} ${GTEST_BOTH_LIBRARIES} components) # Fix for not visible pthreads functions for linker with glibc 2.15 if (UNIX AND NOT APPLE) target_link_libraries(openmw_test_suite ${CMAKE_THREAD_LIBS_INIT}) diff --git a/apps/openmw_test_suite/components/misc/test_slicearray.cpp b/apps/openmw_test_suite/components/misc/test_slicearray.cpp new file mode 100644 index 0000000000..ab63e56c4f --- /dev/null +++ b/apps/openmw_test_suite/components/misc/test_slicearray.cpp @@ -0,0 +1,33 @@ +#include +#include "components/misc/slice_array.hpp" + +struct SliceArrayTest : public ::testing::Test +{ + protected: + virtual void SetUp() + { + } + + virtual void TearDown() + { + } +}; + +TEST_F(SliceArrayTest, hello_string) +{ + Misc::SString s("hello"); + ASSERT_EQ(sizeof("hello") - 1, s.length); + ASSERT_FALSE(s=="hel"); + ASSERT_FALSE(s=="hell"); + ASSERT_TRUE(s=="hello"); +} + +TEST_F(SliceArrayTest, othello_string_with_offset_2_and_size_4) +{ + Misc::SString s("othello" + 2, 4); + ASSERT_EQ(sizeof("hell") - 1, s.length); + ASSERT_FALSE(s=="hel"); + ASSERT_TRUE(s=="hell"); + ASSERT_FALSE(s=="hello"); +} + diff --git a/apps/openmw_test_suite/components/misc/test_stringops.cpp b/apps/openmw_test_suite/components/misc/test_stringops.cpp index b125841966..3ae033db79 100644 --- a/apps/openmw_test_suite/components/misc/test_stringops.cpp +++ b/apps/openmw_test_suite/components/misc/test_stringops.cpp @@ -1,7 +1,79 @@ #include +#include "components/misc/stringops.hpp" -TEST(simple_test, dummy) +struct StringOpsTest : public ::testing::Test { - EXPECT_EQ(true, true); + protected: + virtual void SetUp() + { + } + + virtual void TearDown() + { + } +}; + +TEST_F(StringOpsTest, begins_matching) +{ + ASSERT_EQ(true, Misc::begins("abc", "a")); + ASSERT_EQ(true, Misc::begins("abc", "ab")); + ASSERT_EQ(true, Misc::begins("abc", "abc")); + ASSERT_EQ(true, Misc::begins("abcd", "abc")); +} + +TEST_F(StringOpsTest, begins_not_matching) +{ + ASSERT_EQ(false, Misc::begins("abc", "b")); + ASSERT_EQ(false, Misc::begins("abc", "bc")); + ASSERT_EQ(false, Misc::begins("abc", "bcd")); + ASSERT_EQ(false, Misc::begins("abc", "abcd")); +} + +TEST_F(StringOpsTest, ibegins_matching) +{ + ASSERT_EQ(true, Misc::ibegins("Abc", "a")); + ASSERT_EQ(true, Misc::ibegins("aBc", "ab")); + ASSERT_EQ(true, Misc::ibegins("abC", "abc")); + ASSERT_EQ(true, Misc::ibegins("abcD", "abc")); +} + +TEST_F(StringOpsTest, ibegins_not_matching) +{ + ASSERT_EQ(false, Misc::ibegins("abc", "b")); + ASSERT_EQ(false, Misc::ibegins("abc", "bc")); + ASSERT_EQ(false, Misc::ibegins("abc", "bcd")); + ASSERT_EQ(false, Misc::ibegins("abc", "abcd")); +} + +TEST_F(StringOpsTest, ends_matching) +{ + ASSERT_EQ(true, Misc::ends("abc", "c")); + ASSERT_EQ(true, Misc::ends("abc", "bc")); + ASSERT_EQ(true, Misc::ends("abc", "abc")); + ASSERT_EQ(true, Misc::ends("abcd", "abcd")); +} + +TEST_F(StringOpsTest, ends_not_matching) +{ + ASSERT_EQ(false, Misc::ends("abc", "b")); + ASSERT_EQ(false, Misc::ends("abc", "ab")); + ASSERT_EQ(false, Misc::ends("abc", "bcd")); + ASSERT_EQ(false, Misc::ends("abc", "abcd")); +} + +TEST_F(StringOpsTest, iends_matching) +{ + ASSERT_EQ(true, Misc::iends("Abc", "c")); + ASSERT_EQ(true, Misc::iends("aBc", "bc")); + ASSERT_EQ(true, Misc::iends("abC", "abc")); + ASSERT_EQ(true, Misc::iends("abcD", "abcd")); +} + +TEST_F(StringOpsTest, iends_not_matching) +{ + ASSERT_EQ(false, Misc::iends("abc", "b")); + ASSERT_EQ(false, Misc::iends("abc", "ab")); + ASSERT_EQ(false, Misc::iends("abc", "bcd")); + ASSERT_EQ(false, Misc::iends("abc", "abcd")); } diff --git a/apps/openmw_test_suite/openmw_test_suite.cpp b/apps/openmw_test_suite/openmw_test_suite.cpp index 0a09b3028a..81476325ea 100644 --- a/apps/openmw_test_suite/openmw_test_suite.cpp +++ b/apps/openmw_test_suite/openmw_test_suite.cpp @@ -5,8 +5,8 @@ int main(int argc, char** argv) { // The following line causes Google Mock to throw an exception on failure, // which will be interpreted by your testing framework as a test failure. - ::testing::GTEST_FLAG(throw_on_failure) = true; + ::testing::GTEST_FLAG(throw_on_failure) = false; ::testing::InitGoogleMock(&argc, argv); return RUN_ALL_TESTS(); -} \ No newline at end of file +} From 515a865daafae550756a36f4787f79c65deb015d Mon Sep 17 00:00:00 2001 From: Lukasz Gromanowski Date: Fri, 30 Aug 2013 22:44:03 +0200 Subject: [PATCH 08/15] Changed ASSERT_EQ to ASSERT_TRUE/FALSE. Signed-off-by: Lukasz Gromanowski --- .../components/misc/test_stringops.cpp | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/apps/openmw_test_suite/components/misc/test_stringops.cpp b/apps/openmw_test_suite/components/misc/test_stringops.cpp index 3ae033db79..44587c445f 100644 --- a/apps/openmw_test_suite/components/misc/test_stringops.cpp +++ b/apps/openmw_test_suite/components/misc/test_stringops.cpp @@ -15,65 +15,65 @@ struct StringOpsTest : public ::testing::Test TEST_F(StringOpsTest, begins_matching) { - ASSERT_EQ(true, Misc::begins("abc", "a")); - ASSERT_EQ(true, Misc::begins("abc", "ab")); - ASSERT_EQ(true, Misc::begins("abc", "abc")); - ASSERT_EQ(true, Misc::begins("abcd", "abc")); + ASSERT_TRUE(Misc::begins("abc", "a")); + ASSERT_TRUE(Misc::begins("abc", "ab")); + ASSERT_TRUE(Misc::begins("abc", "abc")); + ASSERT_TRUE(Misc::begins("abcd", "abc")); } TEST_F(StringOpsTest, begins_not_matching) { - ASSERT_EQ(false, Misc::begins("abc", "b")); - ASSERT_EQ(false, Misc::begins("abc", "bc")); - ASSERT_EQ(false, Misc::begins("abc", "bcd")); - ASSERT_EQ(false, Misc::begins("abc", "abcd")); + ASSERT_FALSE(Misc::begins("abc", "b")); + ASSERT_FALSE(Misc::begins("abc", "bc")); + ASSERT_FALSE(Misc::begins("abc", "bcd")); + ASSERT_FALSE(Misc::begins("abc", "abcd")); } TEST_F(StringOpsTest, ibegins_matching) { - ASSERT_EQ(true, Misc::ibegins("Abc", "a")); - ASSERT_EQ(true, Misc::ibegins("aBc", "ab")); - ASSERT_EQ(true, Misc::ibegins("abC", "abc")); - ASSERT_EQ(true, Misc::ibegins("abcD", "abc")); + ASSERT_TRUE(Misc::ibegins("Abc", "a")); + ASSERT_TRUE(Misc::ibegins("aBc", "ab")); + ASSERT_TRUE(Misc::ibegins("abC", "abc")); + ASSERT_TRUE(Misc::ibegins("abcD", "abc")); } TEST_F(StringOpsTest, ibegins_not_matching) { - ASSERT_EQ(false, Misc::ibegins("abc", "b")); - ASSERT_EQ(false, Misc::ibegins("abc", "bc")); - ASSERT_EQ(false, Misc::ibegins("abc", "bcd")); - ASSERT_EQ(false, Misc::ibegins("abc", "abcd")); + ASSERT_FALSE(Misc::ibegins("abc", "b")); + ASSERT_FALSE(Misc::ibegins("abc", "bc")); + ASSERT_FALSE(Misc::ibegins("abc", "bcd")); + ASSERT_FALSE(Misc::ibegins("abc", "abcd")); } TEST_F(StringOpsTest, ends_matching) { - ASSERT_EQ(true, Misc::ends("abc", "c")); - ASSERT_EQ(true, Misc::ends("abc", "bc")); - ASSERT_EQ(true, Misc::ends("abc", "abc")); - ASSERT_EQ(true, Misc::ends("abcd", "abcd")); + ASSERT_TRUE(Misc::ends("abc", "c")); + ASSERT_TRUE(Misc::ends("abc", "bc")); + ASSERT_TRUE(Misc::ends("abc", "abc")); + ASSERT_TRUE(Misc::ends("abcd", "abcd")); } TEST_F(StringOpsTest, ends_not_matching) { - ASSERT_EQ(false, Misc::ends("abc", "b")); - ASSERT_EQ(false, Misc::ends("abc", "ab")); - ASSERT_EQ(false, Misc::ends("abc", "bcd")); - ASSERT_EQ(false, Misc::ends("abc", "abcd")); + ASSERT_FALSE(Misc::ends("abc", "b")); + ASSERT_FALSE(Misc::ends("abc", "ab")); + ASSERT_FALSE(Misc::ends("abc", "bcd")); + ASSERT_FALSE(Misc::ends("abc", "abcd")); } TEST_F(StringOpsTest, iends_matching) { - ASSERT_EQ(true, Misc::iends("Abc", "c")); - ASSERT_EQ(true, Misc::iends("aBc", "bc")); - ASSERT_EQ(true, Misc::iends("abC", "abc")); - ASSERT_EQ(true, Misc::iends("abcD", "abcd")); + ASSERT_TRUE(Misc::iends("Abc", "c")); + ASSERT_TRUE(Misc::iends("aBc", "bc")); + ASSERT_TRUE(Misc::iends("abC", "abc")); + ASSERT_TRUE(Misc::iends("abcD", "abcd")); } TEST_F(StringOpsTest, iends_not_matching) { - ASSERT_EQ(false, Misc::iends("abc", "b")); - ASSERT_EQ(false, Misc::iends("abc", "ab")); - ASSERT_EQ(false, Misc::iends("abc", "bcd")); - ASSERT_EQ(false, Misc::iends("abc", "abcd")); + ASSERT_FALSE(Misc::iends("abc", "b")); + ASSERT_FALSE(Misc::iends("abc", "ab")); + ASSERT_FALSE(Misc::iends("abc", "bcd")); + ASSERT_FALSE(Misc::iends("abc", "abcd")); } From 303e02cab5930155e9d9ce3caa6893d6fbdd56a5 Mon Sep 17 00:00:00 2001 From: Lukasz Gromanowski Date: Fri, 30 Aug 2013 22:45:30 +0200 Subject: [PATCH 09/15] Added unittests for FileFinder::find function. Signed-off-by: Lukasz Gromanowski --- apps/openmw_test_suite/CMakeLists.txt | 1 + .../components/file_finder/test_search.cpp | 74 +++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 apps/openmw_test_suite/components/file_finder/test_search.cpp diff --git a/apps/openmw_test_suite/CMakeLists.txt b/apps/openmw_test_suite/CMakeLists.txt index 9fe7890acc..6820103402 100644 --- a/apps/openmw_test_suite/CMakeLists.txt +++ b/apps/openmw_test_suite/CMakeLists.txt @@ -12,6 +12,7 @@ if (GTEST_FOUND AND GMOCK_FOUND) file(GLOB UNITTEST_SRC_FILES components/misc/test_*.cpp + components/file_finder/test_*.cpp ) source_group(apps\\openmw_test_suite FILES openmw_test_suite.cpp ${UNITTEST_SRC_FILES}) diff --git a/apps/openmw_test_suite/components/file_finder/test_search.cpp b/apps/openmw_test_suite/components/file_finder/test_search.cpp new file mode 100644 index 0000000000..2ca940e6a3 --- /dev/null +++ b/apps/openmw_test_suite/components/file_finder/test_search.cpp @@ -0,0 +1,74 @@ +#include +#include +#include + +#include "components/file_finder/search.hpp" + +struct SearchTest : public ::testing::Test +{ + protected: + SearchTest() + : mTestDir("./test_dir/") + { + } + + virtual void SetUp() + { + boost::filesystem::create_directory(boost::filesystem::path(mTestDir)); + + std::ofstream ofs(std::string(mTestDir + "test2.txt").c_str(), std::ofstream::out); + ofs << std::endl; + ofs.close(); + } + + virtual void TearDown() + { + boost::filesystem::remove_all(boost::filesystem::path(mTestDir)); + } + + std::string mTestDir; +}; + +TEST_F(SearchTest, file_not_found) +{ + struct Result : public FileFinder::ReturnPath + { + Result(const boost::filesystem::path& expectedPath) + : mExpectedPath(expectedPath) + { + } + + void add(const boost::filesystem::path& p) + { + ASSERT_FALSE(p == mExpectedPath); + } + + private: + boost::filesystem::path mExpectedPath; + + } r(boost::filesystem::path(mTestDir + "test.txt")); + + FileFinder::find(mTestDir, r, false); +} + +TEST_F(SearchTest, file_found) +{ + struct Result : public FileFinder::ReturnPath + { + Result(const boost::filesystem::path& expectedPath) + : mExpectedPath(expectedPath) + { + } + + void add(const boost::filesystem::path& p) + { + ASSERT_TRUE(p == mExpectedPath); + } + + private: + boost::filesystem::path mExpectedPath; + + } r(boost::filesystem::path(mTestDir + "test2.txt")); + + FileFinder::find(mTestDir, r, false); +} From 2baaef7d87eface596ab5e23cc113f26583568e1 Mon Sep 17 00:00:00 2001 From: Lukasz Gromanowski Date: Fri, 30 Aug 2013 23:23:34 +0200 Subject: [PATCH 10/15] Added unittests for FileFinder::FileFinder class. Signed-off-by: Lukasz Gromanowski --- .../file_finder/test_filefinder.cpp | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 apps/openmw_test_suite/components/file_finder/test_filefinder.cpp diff --git a/apps/openmw_test_suite/components/file_finder/test_filefinder.cpp b/apps/openmw_test_suite/components/file_finder/test_filefinder.cpp new file mode 100644 index 0000000000..cf34570d77 --- /dev/null +++ b/apps/openmw_test_suite/components/file_finder/test_filefinder.cpp @@ -0,0 +1,52 @@ +//FileFinderT +#include +#include +#include "components/file_finder/file_finder.hpp" + +struct FileFinderTest : public ::testing::Test +{ + protected: + FileFinderTest() + : mTestDir("./filefinder_test_dir/") + , mTestFile("test.txt") + , mTestFileUppercase("TEST.TXT") + , mTestFileNotFound("foobarbaz.txt") + { + } + + virtual void SetUp() + { + boost::filesystem::create_directory(boost::filesystem::path(mTestDir)); + + std::ofstream ofs(std::string(mTestDir + mTestFile).c_str(), std::ofstream::out); + ofs << std::endl; + ofs.close(); + } + + virtual void TearDown() + { + boost::filesystem::remove_all(boost::filesystem::path(mTestDir)); + } + + std::string mTestDir; + std::string mTestFile; + std::string mTestFileUppercase; + std::string mTestFileNotFound; +}; + +TEST_F(FileFinderTest, FileFinder_has_file) +{ + FileFinder::FileFinder fileFinder(mTestDir); + ASSERT_TRUE(fileFinder.has(mTestFile)); + ASSERT_TRUE(fileFinder.has(mTestFileUppercase)); + ASSERT_TRUE(fileFinder.lookup(mTestFile) == std::string(mTestDir + mTestFile)); + ASSERT_TRUE(fileFinder.lookup(mTestFileUppercase) == std::string(mTestDir + mTestFile)); +} + +TEST_F(FileFinderTest, FileFinder_does_not_have_file) +{ + FileFinder::FileFinder fileFinder(mTestDir); + ASSERT_FALSE(fileFinder.has(mTestFileNotFound)); + ASSERT_TRUE(fileFinder.lookup(mTestFileNotFound).empty()); +} + From 0e83b5065953d70a2e7dd354eb468b33ae317a09 Mon Sep 17 00:00:00 2001 From: Lukasz Gromanowski Date: Fri, 30 Aug 2013 23:24:33 +0200 Subject: [PATCH 11/15] Changed test dir for SearchTest. Signed-off-by: Lukasz Gromanowski --- apps/openmw_test_suite/components/file_finder/test_search.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw_test_suite/components/file_finder/test_search.cpp b/apps/openmw_test_suite/components/file_finder/test_search.cpp index 2ca940e6a3..63745b6256 100644 --- a/apps/openmw_test_suite/components/file_finder/test_search.cpp +++ b/apps/openmw_test_suite/components/file_finder/test_search.cpp @@ -8,7 +8,7 @@ struct SearchTest : public ::testing::Test { protected: SearchTest() - : mTestDir("./test_dir/") + : mTestDir("./search_test_dir/") { } From 2c49458b6cfa5164d425248051c9c48ea84819b3 Mon Sep 17 00:00:00 2001 From: Lukasz Gromanowski Date: Sat, 31 Aug 2013 00:13:42 +0200 Subject: [PATCH 12/15] Added unittests for FileFinder::FileFinderStrict class. Signed-off-by: Lukasz Gromanowski --- .../components/file_finder/test_filefinder.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/apps/openmw_test_suite/components/file_finder/test_filefinder.cpp b/apps/openmw_test_suite/components/file_finder/test_filefinder.cpp index cf34570d77..2d151988b9 100644 --- a/apps/openmw_test_suite/components/file_finder/test_filefinder.cpp +++ b/apps/openmw_test_suite/components/file_finder/test_filefinder.cpp @@ -1,4 +1,3 @@ -//FileFinderT #include #include #include "components/file_finder/file_finder.hpp" @@ -50,3 +49,18 @@ TEST_F(FileFinderTest, FileFinder_does_not_have_file) ASSERT_TRUE(fileFinder.lookup(mTestFileNotFound).empty()); } +TEST_F(FileFinderTest, FileFinderStrict_has_file) +{ + FileFinder::FileFinderStrict fileFinder(mTestDir); + ASSERT_TRUE(fileFinder.has(mTestFile)); + ASSERT_FALSE(fileFinder.has(mTestFileUppercase)); + ASSERT_TRUE(fileFinder.lookup(mTestFile) == std::string(mTestDir + mTestFile)); + ASSERT_FALSE(fileFinder.lookup(mTestFileUppercase) == std::string(mTestDir + mTestFile)); +} + +TEST_F(FileFinderTest, FileFinderStrict_does_not_have_file) +{ + FileFinder::FileFinderStrict fileFinder(mTestDir); + ASSERT_FALSE(fileFinder.has(mTestFileNotFound)); + ASSERT_TRUE(fileFinder.lookup(mTestFileNotFound).empty()); +} From 3ddeb075fbba25ca4aac64bd9282ec4d9da791e0 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 31 Aug 2013 04:36:23 +0200 Subject: [PATCH 13/15] Fix a cell border seam on the map --- apps/openmw/mwrender/localmap.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index c414844520..5f41289788 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -370,8 +370,8 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni MWBase::Environment::get().getWindowManager()->setPlayerDir(playerdirection.x, playerdirection.y); // explore radius (squared) - const float sqrExploreRadius = (mInterior ? 0.01 : 0.09) * sFogOfWarResolution*sFogOfWarResolution; - const float exploreRadius = (mInterior ? 0.1 : 0.3) * sFogOfWarResolution; // explore radius from 0 to sFogOfWarResolution + const float exploreRadius = (mInterior ? 0.1 : 0.3) * (sFogOfWarResolution-1); // explore radius from 0 to sFogOfWarResolution-1 + const float sqrExploreRadius = Math::Sqr(exploreRadius); const float exploreRadiusUV = exploreRadius / sFogOfWarResolution; // explore radius from 0 to 1 (UV space) // change the affected fog of war textures (in a 3x3 grid around the player) @@ -406,11 +406,8 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni { for (int texU = 0; texU> 24); alpha = std::min( alpha, (uint8) (std::max(0.f, std::min(1.f, (sqrDist/sqrExploreRadius)))*255) ); From f9cfe654f2f15bf9e774f625395f7a0e9ef663d9 Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Sun, 1 Sep 2013 23:17:41 +0400 Subject: [PATCH 14/15] Workaround for https://bugreports.qt-project.org/browse/QTBUG-22154 (Qt redefines min OS X version and SDL in turn checks this version and doesn't accept version set by Qt) --- apps/launcher/graphicspage.cpp | 5 +++++ apps/launcher/main.cpp | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index 1bbf7f8973..9308c1d572 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -3,6 +3,11 @@ #include #include #include + +#ifdef __APPLE__ +// We need to do this because of Qt: https://bugreports.qt-project.org/browse/QTBUG-22154 +#define MAC_OS_X_VERSION_MIN_REQUIRED __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ +#endif #include #include diff --git a/apps/launcher/main.cpp b/apps/launcher/main.cpp index dfe2d74132..f67f5edcff 100644 --- a/apps/launcher/main.cpp +++ b/apps/launcher/main.cpp @@ -3,6 +3,10 @@ #include #include +#ifdef __APPLE__ +// We need to do this because of Qt: https://bugreports.qt-project.org/browse/QTBUG-22154 +#define MAC_OS_X_VERSION_MIN_REQUIRED __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ +#endif #include #include "maindialog.hpp" From 4dbacdc6bd0172942617f2470e70b3b3321a62c5 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 2 Sep 2013 10:58:58 +0200 Subject: [PATCH 15/15] increased version number --- CMakeLists.txt | 2 +- readme.txt | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d6daf9f00..3f95f2d4e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,7 @@ include (OpenMWMacros) # Version set (OPENMW_VERSION_MAJOR 0) -set (OPENMW_VERSION_MINOR 25) +set (OPENMW_VERSION_MINOR 26) set (OPENMW_VERSION_RELEASE 0) set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}") diff --git a/readme.txt b/readme.txt index d00a959a01..ade5da04de 100644 --- a/readme.txt +++ b/readme.txt @@ -3,7 +3,7 @@ OpenMW: A reimplementation of The Elder Scrolls III: Morrowind OpenMW is an attempt at recreating the engine for the popular role-playing game Morrowind by Bethesda Softworks. You need to own and install the original game for OpenMW to work. -Version: 0.25.0 +Version: 0.26.0 License: GPL (see GPL3.txt for more information) Website: http://www.openmw.org @@ -71,13 +71,13 @@ Allowed options: --new-game [=arg(=1)] (=0) activate char gen/new game mechanics --fs-strict [=arg(=1)] (=0) strict file system handling (no case folding) --encoding arg (=win1252) Character encoding used in OpenMW game messages: - + win1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, Croatian, Serbian (Latin script), Romanian and Albanian languages - + win1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages - + win1252 - Western European (Latin) alphabet, used by default - + --fallback arg fallback values CHANGELOG