From 84f8a6848a8b05502d7618ca7af8cca74f2c3bae Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Fri, 16 Sep 2022 00:53:24 +0100 Subject: [PATCH] Renormalise line endings This should replace accidental CRLF with LF --- apps/openmw/mwmechanics/aiactivate.cpp | 126 +- apps/openmw/mwmechanics/aiactivate.hpp | 80 +- apps/openmw/mwmechanics/aiescort.cpp | 246 +-- apps/openmw/mwmechanics/aitravel.hpp | 142 +- components/esm3/weatherstate.cpp | 150 +- components/esm3/weatherstate.hpp | 72 +- components/myguiplatform/myguiloglistener.cpp | 80 +- components/myguiplatform/myguiloglistener.hpp | 136 +- components/sceneutil/clearcolor.hpp | 84 +- extern/oics/ICSChannel.cpp | 530 ++--- extern/oics/ICSChannel.h | 252 +-- extern/oics/ICSChannelListener.h | 96 +- extern/oics/ICSControl.cpp | 322 +-- extern/oics/ICSControl.h | 214 +- extern/oics/ICSControlListener.h | 96 +- extern/oics/ICSInputControlSystem.cpp | 1634 +++++++-------- extern/oics/ICSInputControlSystem.h | 562 ++--- .../oics/ICSInputControlSystem_joystick.cpp | 620 +++--- .../oics/ICSInputControlSystem_keyboard.cpp | 314 +-- extern/oics/ICSInputControlSystem_mouse.cpp | 1132 +++++------ extern/oics/ICSPrerequisites.cpp | 54 +- extern/oics/ICSPrerequisites.h | 220 +- extern/sol3/sol/assert.hpp | 198 +- extern/sol3/sol/base_traits.hpp | 246 +-- extern/sol3/sol/bytecode.hpp | 242 +-- extern/sol3/sol/compatibility/compat-5.3.c.h | 1800 ++++++++--------- extern/sol3/sol/compatibility/compat-5.3.h | 848 ++++---- extern/sol3/sol/compatibility/compat-5.4.h | 48 +- extern/sol3/sol/debug.hpp | 104 +- extern/sol3/sol/deprecate.hpp | 88 +- extern/sol3/sol/detail/build_version.hpp | 464 ++--- extern/sol3/sol/dump_handler.hpp | 154 +- extern/sol3/sol/ebco.hpp | 320 +-- extern/sol3/sol/epilogue.hpp | 78 +- extern/sol3/sol/error.hpp | 178 +- extern/sol3/sol/function.hpp | 284 +-- extern/sol3/sol/inheritance.hpp | 390 ++-- extern/sol3/sol/lua_table.hpp | 190 +- extern/sol3/sol/lua_value.hpp | 324 +-- extern/sol3/sol/packaged_coroutine.hpp | 524 ++--- extern/sol3/sol/pairs_iterator.hpp | 550 ++--- extern/sol3/sol/pointer_like.hpp | 204 +- extern/sol3/sol/prologue.hpp | 94 +- extern/sol3/sol/stack.hpp | 702 +++---- extern/sol3/sol/stack/detail/pairs.hpp | 196 +- extern/sol3/sol/table.hpp | 232 +-- extern/sol3/sol/tuple.hpp | 186 +- extern/sol3/sol/unicode.hpp | 616 +++--- extern/sol3/sol/unique_usertype_traits.hpp | 480 ++--- extern/sol3/sol/usertype_traits.hpp | 122 +- files/lua_api/coroutine.doclua | 142 +- files/lua_api/global.doclua | 538 ++--- files/lua_api/math.doclua | 400 ++-- files/lua_api/string.doclua | 462 ++--- files/lua_api/table.doclua | 132 +- manual/opencs/creating_file.tex | 48 +- manual/opencs/files_and_directories.tex | 234 +-- manual/opencs/filters.tex | 404 ++-- manual/opencs/main.tex | 74 +- manual/opencs/recordtypes.tex | 36 +- manual/opencs/tables.tex | 188 +- manual/opencs/windows.tex | 106 +- 62 files changed, 9894 insertions(+), 9894 deletions(-) diff --git a/apps/openmw/mwmechanics/aiactivate.cpp b/apps/openmw/mwmechanics/aiactivate.cpp index ece071c601..d5bb335936 100644 --- a/apps/openmw/mwmechanics/aiactivate.cpp +++ b/apps/openmw/mwmechanics/aiactivate.cpp @@ -1,63 +1,63 @@ -#include "aiactivate.hpp" - -#include - -#include "../mwbase/world.hpp" -#include "../mwbase/environment.hpp" - -#include "../mwworld/class.hpp" - -#include "creaturestats.hpp" -#include "movement.hpp" -#include "steering.hpp" - -namespace MWMechanics -{ - AiActivate::AiActivate(std::string_view objectId, bool repeat) - : TypedAiPackage(repeat), mObjectId(objectId) - { - } - - bool AiActivate::execute(const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) - { - const MWWorld::Ptr target = MWBase::Environment::get().getWorld()->searchPtr(mObjectId, false); //The target to follow - - actor.getClass().getCreatureStats(actor).setDrawState(DrawState::Nothing); - - // Stop if the target doesn't exist - // Really we should be checking whether the target is currently registered with the MechanicsManager - if (target == MWWorld::Ptr() || !target.getRefData().getCount() || !target.getRefData().isEnabled()) - return true; - - // Turn to target and move to it directly, without pathfinding. - const osg::Vec3f targetDir = target.getRefData().getPosition().asVec3() - actor.getRefData().getPosition().asVec3(); - - zTurn(actor, std::atan2(targetDir.x(), targetDir.y()), 0.f); - actor.getClass().getMovementSettings(actor).mPosition[1] = 1; - actor.getClass().getMovementSettings(actor).mPosition[0] = 0; - - if (MWBase::Environment::get().getWorld()->getMaxActivationDistance() >= targetDir.length()) - { - // Note: we intentionally do not cancel package after activation here for backward compatibility with original engine. - MWBase::Environment::get().getWorld()->activate(target, actor); - } - return false; - } - - void AiActivate::writeState(ESM::AiSequence::AiSequence &sequence) const - { - auto activate = std::make_unique(); - activate->mTargetId = mObjectId; - activate->mRepeat = getRepeat(); - - ESM::AiSequence::AiPackageContainer package; - package.mType = ESM::AiSequence::Ai_Activate; - package.mPackage = std::move(activate); - sequence.mPackages.push_back(std::move(package)); - } - - AiActivate::AiActivate(const ESM::AiSequence::AiActivate *activate) - : AiActivate(activate->mTargetId, activate->mRepeat) - { - } -} +#include "aiactivate.hpp" + +#include + +#include "../mwbase/world.hpp" +#include "../mwbase/environment.hpp" + +#include "../mwworld/class.hpp" + +#include "creaturestats.hpp" +#include "movement.hpp" +#include "steering.hpp" + +namespace MWMechanics +{ + AiActivate::AiActivate(std::string_view objectId, bool repeat) + : TypedAiPackage(repeat), mObjectId(objectId) + { + } + + bool AiActivate::execute(const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) + { + const MWWorld::Ptr target = MWBase::Environment::get().getWorld()->searchPtr(mObjectId, false); //The target to follow + + actor.getClass().getCreatureStats(actor).setDrawState(DrawState::Nothing); + + // Stop if the target doesn't exist + // Really we should be checking whether the target is currently registered with the MechanicsManager + if (target == MWWorld::Ptr() || !target.getRefData().getCount() || !target.getRefData().isEnabled()) + return true; + + // Turn to target and move to it directly, without pathfinding. + const osg::Vec3f targetDir = target.getRefData().getPosition().asVec3() - actor.getRefData().getPosition().asVec3(); + + zTurn(actor, std::atan2(targetDir.x(), targetDir.y()), 0.f); + actor.getClass().getMovementSettings(actor).mPosition[1] = 1; + actor.getClass().getMovementSettings(actor).mPosition[0] = 0; + + if (MWBase::Environment::get().getWorld()->getMaxActivationDistance() >= targetDir.length()) + { + // Note: we intentionally do not cancel package after activation here for backward compatibility with original engine. + MWBase::Environment::get().getWorld()->activate(target, actor); + } + return false; + } + + void AiActivate::writeState(ESM::AiSequence::AiSequence &sequence) const + { + auto activate = std::make_unique(); + activate->mTargetId = mObjectId; + activate->mRepeat = getRepeat(); + + ESM::AiSequence::AiPackageContainer package; + package.mType = ESM::AiSequence::Ai_Activate; + package.mPackage = std::move(activate); + sequence.mPackages.push_back(std::move(package)); + } + + AiActivate::AiActivate(const ESM::AiSequence::AiActivate *activate) + : AiActivate(activate->mTargetId, activate->mRepeat) + { + } +} diff --git a/apps/openmw/mwmechanics/aiactivate.hpp b/apps/openmw/mwmechanics/aiactivate.hpp index fbd36b6512..f8686d746b 100644 --- a/apps/openmw/mwmechanics/aiactivate.hpp +++ b/apps/openmw/mwmechanics/aiactivate.hpp @@ -1,40 +1,40 @@ -#ifndef GAME_MWMECHANICS_AIACTIVATE_H -#define GAME_MWMECHANICS_AIACTIVATE_H - -#include "typedaipackage.hpp" - -#include -#include - -namespace ESM -{ -namespace AiSequence -{ - struct AiActivate; -} -} - -namespace MWMechanics -{ - /// \brief Causes actor to walk to activatable object and activate it - /** Will activate when close to object **/ - class AiActivate final : public TypedAiPackage - { - public: - /// Constructor - /** \param objectId Reference to object to activate **/ - explicit AiActivate(std::string_view objectId, bool repeat); - - explicit AiActivate(const ESM::AiSequence::AiActivate* activate); - - bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override; - - static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Activate; } - - void writeState(ESM::AiSequence::AiSequence& sequence) const override; - - private: - const std::string mObjectId; - }; -} -#endif // GAME_MWMECHANICS_AIACTIVATE_H +#ifndef GAME_MWMECHANICS_AIACTIVATE_H +#define GAME_MWMECHANICS_AIACTIVATE_H + +#include "typedaipackage.hpp" + +#include +#include + +namespace ESM +{ +namespace AiSequence +{ + struct AiActivate; +} +} + +namespace MWMechanics +{ + /// \brief Causes actor to walk to activatable object and activate it + /** Will activate when close to object **/ + class AiActivate final : public TypedAiPackage + { + public: + /// Constructor + /** \param objectId Reference to object to activate **/ + explicit AiActivate(std::string_view objectId, bool repeat); + + explicit AiActivate(const ESM::AiSequence::AiActivate* activate); + + bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override; + + static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Activate; } + + void writeState(ESM::AiSequence::AiSequence& sequence) const override; + + private: + const std::string mObjectId; + }; +} +#endif // GAME_MWMECHANICS_AIACTIVATE_H diff --git a/apps/openmw/mwmechanics/aiescort.cpp b/apps/openmw/mwmechanics/aiescort.cpp index 0426035b8d..bbbab3b5a8 100644 --- a/apps/openmw/mwmechanics/aiescort.cpp +++ b/apps/openmw/mwmechanics/aiescort.cpp @@ -1,123 +1,123 @@ -#include "aiescort.hpp" - -#include -#include - -#include "../mwbase/world.hpp" -#include "../mwbase/environment.hpp" -#include "../mwbase/mechanicsmanager.hpp" - -#include "../mwworld/class.hpp" -#include "../mwworld/cellstore.hpp" - -#include "creaturestats.hpp" -#include "movement.hpp" - -/* - TODO: Different behavior for AIEscort a d x y z and AIEscortCell a c d x y z. - TODO: Take account for actors being in different cells. -*/ - -namespace MWMechanics -{ - AiEscort::AiEscort(std::string_view actorId, int duration, float x, float y, float z, bool repeat) - : TypedAiPackage(repeat), mX(x), mY(y), mZ(z), mDuration(duration), mRemainingDuration(static_cast(duration)) - , mCellX(std::numeric_limits::max()) - , mCellY(std::numeric_limits::max()) - { - mTargetActorRefId = std::string(actorId); - } - - AiEscort::AiEscort(std::string_view actorId, std::string_view cellId, int duration, float x, float y, float z, bool repeat) - : TypedAiPackage(repeat), mCellId(cellId), mX(x), mY(y), mZ(z), mDuration(duration), mRemainingDuration(static_cast(duration)) - , mCellX(std::numeric_limits::max()) - , mCellY(std::numeric_limits::max()) - { - mTargetActorRefId = std::string(actorId); - } - - AiEscort::AiEscort(const ESM::AiSequence::AiEscort *escort) - : TypedAiPackage(escort->mRepeat), mCellId(escort->mCellId), mX(escort->mData.mX), mY(escort->mData.mY), mZ(escort->mData.mZ) - , mDuration(escort->mData.mDuration) - , mRemainingDuration(escort->mRemainingDuration) - , mCellX(std::numeric_limits::max()) - , mCellY(std::numeric_limits::max()) - { - mTargetActorRefId = escort->mTargetId; - mTargetActorId = escort->mTargetActorId; - } - - bool AiEscort::execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) - { - // If AiEscort has ran for as long or longer then the duration specified - // and the duration is not infinite, the package is complete. - if (mDuration > 0) - { - mRemainingDuration -= ((duration*MWBase::Environment::get().getWorld()->getTimeScaleFactor()) / 3600); - if (mRemainingDuration <= 0) - { - mRemainingDuration = mDuration; - return true; - } - } - - if (!mCellId.empty() && mCellId != actor.getCell()->getCell()->getCellId().mWorldspace) - return false; // Not in the correct cell, pause and rely on the player to go back through a teleport door - - actor.getClass().getCreatureStats(actor).setDrawState(DrawState::Nothing); - actor.getClass().getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, false); - - const MWWorld::Ptr follower = MWBase::Environment::get().getWorld()->getPtr(mTargetActorRefId, false); - const osg::Vec3f leaderPos = actor.getRefData().getPosition().asVec3(); - const osg::Vec3f followerPos = follower.getRefData().getPosition().asVec3(); - const osg::Vec3f halfExtents = MWBase::Environment::get().getWorld()->getHalfExtents(actor); - const float maxHalfExtent = std::max(halfExtents.x(), std::max(halfExtents.y(), halfExtents.z())); - - if ((leaderPos - followerPos).length2() <= mMaxDist * mMaxDist) - { - const osg::Vec3f dest(mX, mY, mZ); - if (pathTo(actor, dest, duration, maxHalfExtent)) //Returns true on path complete - { - mRemainingDuration = mDuration; - return true; - } - mMaxDist = maxHalfExtent + 450.0f; - } - else - { - // Stop moving if the player is too far away - MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle3", 0, 1); - actor.getClass().getMovementSettings(actor).mPosition[1] = 0; - mMaxDist = maxHalfExtent + 250.0f; - } - - return false; - } - - void AiEscort::writeState(ESM::AiSequence::AiSequence &sequence) const - { - auto escort = std::make_unique(); - escort->mData.mX = mX; - escort->mData.mY = mY; - escort->mData.mZ = mZ; - escort->mData.mDuration = mDuration; - escort->mTargetId = mTargetActorRefId; - escort->mTargetActorId = mTargetActorId; - escort->mRemainingDuration = mRemainingDuration; - escort->mCellId = mCellId; - escort->mRepeat = getRepeat(); - - ESM::AiSequence::AiPackageContainer package; - package.mType = ESM::AiSequence::Ai_Escort; - package.mPackage = std::move(escort); - sequence.mPackages.push_back(std::move(package)); - } - - void AiEscort::fastForward(const MWWorld::Ptr& actor, AiState &state) - { - // Update duration counter if this package has a duration - if (mDuration > 0) - mRemainingDuration--; - } -} - +#include "aiescort.hpp" + +#include +#include + +#include "../mwbase/world.hpp" +#include "../mwbase/environment.hpp" +#include "../mwbase/mechanicsmanager.hpp" + +#include "../mwworld/class.hpp" +#include "../mwworld/cellstore.hpp" + +#include "creaturestats.hpp" +#include "movement.hpp" + +/* + TODO: Different behavior for AIEscort a d x y z and AIEscortCell a c d x y z. + TODO: Take account for actors being in different cells. +*/ + +namespace MWMechanics +{ + AiEscort::AiEscort(std::string_view actorId, int duration, float x, float y, float z, bool repeat) + : TypedAiPackage(repeat), mX(x), mY(y), mZ(z), mDuration(duration), mRemainingDuration(static_cast(duration)) + , mCellX(std::numeric_limits::max()) + , mCellY(std::numeric_limits::max()) + { + mTargetActorRefId = std::string(actorId); + } + + AiEscort::AiEscort(std::string_view actorId, std::string_view cellId, int duration, float x, float y, float z, bool repeat) + : TypedAiPackage(repeat), mCellId(cellId), mX(x), mY(y), mZ(z), mDuration(duration), mRemainingDuration(static_cast(duration)) + , mCellX(std::numeric_limits::max()) + , mCellY(std::numeric_limits::max()) + { + mTargetActorRefId = std::string(actorId); + } + + AiEscort::AiEscort(const ESM::AiSequence::AiEscort *escort) + : TypedAiPackage(escort->mRepeat), mCellId(escort->mCellId), mX(escort->mData.mX), mY(escort->mData.mY), mZ(escort->mData.mZ) + , mDuration(escort->mData.mDuration) + , mRemainingDuration(escort->mRemainingDuration) + , mCellX(std::numeric_limits::max()) + , mCellY(std::numeric_limits::max()) + { + mTargetActorRefId = escort->mTargetId; + mTargetActorId = escort->mTargetActorId; + } + + bool AiEscort::execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) + { + // If AiEscort has ran for as long or longer then the duration specified + // and the duration is not infinite, the package is complete. + if (mDuration > 0) + { + mRemainingDuration -= ((duration*MWBase::Environment::get().getWorld()->getTimeScaleFactor()) / 3600); + if (mRemainingDuration <= 0) + { + mRemainingDuration = mDuration; + return true; + } + } + + if (!mCellId.empty() && mCellId != actor.getCell()->getCell()->getCellId().mWorldspace) + return false; // Not in the correct cell, pause and rely on the player to go back through a teleport door + + actor.getClass().getCreatureStats(actor).setDrawState(DrawState::Nothing); + actor.getClass().getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, false); + + const MWWorld::Ptr follower = MWBase::Environment::get().getWorld()->getPtr(mTargetActorRefId, false); + const osg::Vec3f leaderPos = actor.getRefData().getPosition().asVec3(); + const osg::Vec3f followerPos = follower.getRefData().getPosition().asVec3(); + const osg::Vec3f halfExtents = MWBase::Environment::get().getWorld()->getHalfExtents(actor); + const float maxHalfExtent = std::max(halfExtents.x(), std::max(halfExtents.y(), halfExtents.z())); + + if ((leaderPos - followerPos).length2() <= mMaxDist * mMaxDist) + { + const osg::Vec3f dest(mX, mY, mZ); + if (pathTo(actor, dest, duration, maxHalfExtent)) //Returns true on path complete + { + mRemainingDuration = mDuration; + return true; + } + mMaxDist = maxHalfExtent + 450.0f; + } + else + { + // Stop moving if the player is too far away + MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle3", 0, 1); + actor.getClass().getMovementSettings(actor).mPosition[1] = 0; + mMaxDist = maxHalfExtent + 250.0f; + } + + return false; + } + + void AiEscort::writeState(ESM::AiSequence::AiSequence &sequence) const + { + auto escort = std::make_unique(); + escort->mData.mX = mX; + escort->mData.mY = mY; + escort->mData.mZ = mZ; + escort->mData.mDuration = mDuration; + escort->mTargetId = mTargetActorRefId; + escort->mTargetActorId = mTargetActorId; + escort->mRemainingDuration = mRemainingDuration; + escort->mCellId = mCellId; + escort->mRepeat = getRepeat(); + + ESM::AiSequence::AiPackageContainer package; + package.mType = ESM::AiSequence::Ai_Escort; + package.mPackage = std::move(escort); + sequence.mPackages.push_back(std::move(package)); + } + + void AiEscort::fastForward(const MWWorld::Ptr& actor, AiState &state) + { + // Update duration counter if this package has a duration + if (mDuration > 0) + mRemainingDuration--; + } +} + diff --git a/apps/openmw/mwmechanics/aitravel.hpp b/apps/openmw/mwmechanics/aitravel.hpp index 60a68d9cc5..dde63b3aa4 100644 --- a/apps/openmw/mwmechanics/aitravel.hpp +++ b/apps/openmw/mwmechanics/aitravel.hpp @@ -1,71 +1,71 @@ -#ifndef GAME_MWMECHANICS_AITRAVEL_H -#define GAME_MWMECHANICS_AITRAVEL_H - -#include "typedaipackage.hpp" - -namespace ESM -{ -namespace AiSequence -{ - struct AiTravel; -} -} - -namespace MWMechanics -{ - struct AiInternalTravel; - - /// \brief Causes the AI to travel to the specified point - class AiTravel : public TypedAiPackage - { - public: - AiTravel(float x, float y, float z, bool repeat, AiTravel* derived); - - AiTravel(float x, float y, float z, AiInternalTravel* derived); - - AiTravel(float x, float y, float z, bool repeat); - - explicit AiTravel(const ESM::AiSequence::AiTravel* travel); - - /// Simulates the passing of time - void fastForward(const MWWorld::Ptr& actor, AiState& state) override; - - void writeState(ESM::AiSequence::AiSequence &sequence) const override; - - bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override; - - static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Travel; } - - static constexpr Options makeDefaultOptions() - { - AiPackage::Options options; - options.mUseVariableSpeed = true; - options.mAlwaysActive = true; - return options; - } - - osg::Vec3f getDestination() const override { return osg::Vec3f(mX, mY, mZ); } - - private: - const float mX; - const float mY; - const float mZ; - - const bool mHidden; - - float mDestinationTimer; - }; - - struct AiInternalTravel final : public AiTravel - { - AiInternalTravel(float x, float y, float z); - - explicit AiInternalTravel(const ESM::AiSequence::AiTravel* travel); - - static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::InternalTravel; } - - std::unique_ptr clone() const override; - }; -} - -#endif +#ifndef GAME_MWMECHANICS_AITRAVEL_H +#define GAME_MWMECHANICS_AITRAVEL_H + +#include "typedaipackage.hpp" + +namespace ESM +{ +namespace AiSequence +{ + struct AiTravel; +} +} + +namespace MWMechanics +{ + struct AiInternalTravel; + + /// \brief Causes the AI to travel to the specified point + class AiTravel : public TypedAiPackage + { + public: + AiTravel(float x, float y, float z, bool repeat, AiTravel* derived); + + AiTravel(float x, float y, float z, AiInternalTravel* derived); + + AiTravel(float x, float y, float z, bool repeat); + + explicit AiTravel(const ESM::AiSequence::AiTravel* travel); + + /// Simulates the passing of time + void fastForward(const MWWorld::Ptr& actor, AiState& state) override; + + void writeState(ESM::AiSequence::AiSequence &sequence) const override; + + bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override; + + static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Travel; } + + static constexpr Options makeDefaultOptions() + { + AiPackage::Options options; + options.mUseVariableSpeed = true; + options.mAlwaysActive = true; + return options; + } + + osg::Vec3f getDestination() const override { return osg::Vec3f(mX, mY, mZ); } + + private: + const float mX; + const float mY; + const float mZ; + + const bool mHidden; + + float mDestinationTimer; + }; + + struct AiInternalTravel final : public AiTravel + { + AiInternalTravel(float x, float y, float z); + + explicit AiInternalTravel(const ESM::AiSequence::AiTravel* travel); + + static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::InternalTravel; } + + std::unique_ptr clone() const override; + }; +} + +#endif diff --git a/components/esm3/weatherstate.cpp b/components/esm3/weatherstate.cpp index b149c2bfe0..b148bc8045 100644 --- a/components/esm3/weatherstate.cpp +++ b/components/esm3/weatherstate.cpp @@ -1,75 +1,75 @@ -#include "weatherstate.hpp" - -#include "esmreader.hpp" -#include "esmwriter.hpp" - -namespace ESM -{ -namespace -{ - constexpr NAME currentRegionRecord = "CREG"; - constexpr NAME timePassedRecord = "TMPS"; - constexpr NAME fastForwardRecord = "FAST"; - constexpr NAME weatherUpdateTimeRecord = "WUPD"; - constexpr NAME transitionFactorRecord = "TRFC"; - constexpr NAME currentWeatherRecord = "CWTH"; - constexpr NAME nextWeatherRecord = "NWTH"; - constexpr NAME queuedWeatherRecord = "QWTH"; - constexpr NAME regionNameRecord = "RGNN"; - constexpr NAME regionWeatherRecord = "RGNW"; - constexpr NAME regionChanceRecord = "RGNC"; -} -} - -namespace ESM -{ - void WeatherState::load(ESMReader& esm) - { - mCurrentRegion = esm.getHNString(currentRegionRecord); - esm.getHNT(mTimePassed, timePassedRecord); - esm.getHNT(mFastForward, fastForwardRecord); - esm.getHNT(mWeatherUpdateTime, weatherUpdateTimeRecord); - esm.getHNT(mTransitionFactor, transitionFactorRecord); - esm.getHNT(mCurrentWeather, currentWeatherRecord); - esm.getHNT(mNextWeather, nextWeatherRecord); - esm.getHNT(mQueuedWeather, queuedWeatherRecord); - - while (esm.isNextSub(regionNameRecord)) - { - std::string regionID = esm.getHString(); - RegionWeatherState region; - esm.getHNT(region.mWeather, regionWeatherRecord); - while (esm.isNextSub(regionChanceRecord)) - { - char chance; - esm.getHT(chance); - region.mChances.push_back(chance); - } - - mRegions.insert(std::make_pair(regionID, region)); - } - } - - void WeatherState::save(ESMWriter& esm) const - { - esm.writeHNCString(currentRegionRecord, mCurrentRegion); - esm.writeHNT(timePassedRecord, mTimePassed); - esm.writeHNT(fastForwardRecord, mFastForward); - esm.writeHNT(weatherUpdateTimeRecord, mWeatherUpdateTime); - esm.writeHNT(transitionFactorRecord, mTransitionFactor); - esm.writeHNT(currentWeatherRecord, mCurrentWeather); - esm.writeHNT(nextWeatherRecord, mNextWeather); - esm.writeHNT(queuedWeatherRecord, mQueuedWeather); - - std::map::const_iterator it = mRegions.begin(); - for(; it != mRegions.end(); ++it) - { - esm.writeHNCString(regionNameRecord, it->first.c_str()); - esm.writeHNT(regionWeatherRecord, it->second.mWeather); - for(size_t i = 0; i < it->second.mChances.size(); ++i) - { - esm.writeHNT(regionChanceRecord, it->second.mChances[i]); - } - } - } -} +#include "weatherstate.hpp" + +#include "esmreader.hpp" +#include "esmwriter.hpp" + +namespace ESM +{ +namespace +{ + constexpr NAME currentRegionRecord = "CREG"; + constexpr NAME timePassedRecord = "TMPS"; + constexpr NAME fastForwardRecord = "FAST"; + constexpr NAME weatherUpdateTimeRecord = "WUPD"; + constexpr NAME transitionFactorRecord = "TRFC"; + constexpr NAME currentWeatherRecord = "CWTH"; + constexpr NAME nextWeatherRecord = "NWTH"; + constexpr NAME queuedWeatherRecord = "QWTH"; + constexpr NAME regionNameRecord = "RGNN"; + constexpr NAME regionWeatherRecord = "RGNW"; + constexpr NAME regionChanceRecord = "RGNC"; +} +} + +namespace ESM +{ + void WeatherState::load(ESMReader& esm) + { + mCurrentRegion = esm.getHNString(currentRegionRecord); + esm.getHNT(mTimePassed, timePassedRecord); + esm.getHNT(mFastForward, fastForwardRecord); + esm.getHNT(mWeatherUpdateTime, weatherUpdateTimeRecord); + esm.getHNT(mTransitionFactor, transitionFactorRecord); + esm.getHNT(mCurrentWeather, currentWeatherRecord); + esm.getHNT(mNextWeather, nextWeatherRecord); + esm.getHNT(mQueuedWeather, queuedWeatherRecord); + + while (esm.isNextSub(regionNameRecord)) + { + std::string regionID = esm.getHString(); + RegionWeatherState region; + esm.getHNT(region.mWeather, regionWeatherRecord); + while (esm.isNextSub(regionChanceRecord)) + { + char chance; + esm.getHT(chance); + region.mChances.push_back(chance); + } + + mRegions.insert(std::make_pair(regionID, region)); + } + } + + void WeatherState::save(ESMWriter& esm) const + { + esm.writeHNCString(currentRegionRecord, mCurrentRegion); + esm.writeHNT(timePassedRecord, mTimePassed); + esm.writeHNT(fastForwardRecord, mFastForward); + esm.writeHNT(weatherUpdateTimeRecord, mWeatherUpdateTime); + esm.writeHNT(transitionFactorRecord, mTransitionFactor); + esm.writeHNT(currentWeatherRecord, mCurrentWeather); + esm.writeHNT(nextWeatherRecord, mNextWeather); + esm.writeHNT(queuedWeatherRecord, mQueuedWeather); + + std::map::const_iterator it = mRegions.begin(); + for(; it != mRegions.end(); ++it) + { + esm.writeHNCString(regionNameRecord, it->first.c_str()); + esm.writeHNT(regionWeatherRecord, it->second.mWeather); + for(size_t i = 0; i < it->second.mChances.size(); ++i) + { + esm.writeHNT(regionChanceRecord, it->second.mChances[i]); + } + } + } +} diff --git a/components/esm3/weatherstate.hpp b/components/esm3/weatherstate.hpp index 532a056ac0..e2416ef5d5 100644 --- a/components/esm3/weatherstate.hpp +++ b/components/esm3/weatherstate.hpp @@ -1,36 +1,36 @@ -#ifndef OPENMW_ESM_WEATHERSTATE_H -#define OPENMW_ESM_WEATHERSTATE_H - -#include -#include -#include - -namespace ESM -{ - class ESMReader; - class ESMWriter; - - struct RegionWeatherState - { - int mWeather; - std::vector mChances; - }; - - struct WeatherState - { - std::string mCurrentRegion; - float mTimePassed; - bool mFastForward; - float mWeatherUpdateTime; - float mTransitionFactor; - int mCurrentWeather; - int mNextWeather; - int mQueuedWeather; - std::map mRegions; - - void load(ESMReader& esm); - void save(ESMWriter& esm) const; - }; -} - -#endif +#ifndef OPENMW_ESM_WEATHERSTATE_H +#define OPENMW_ESM_WEATHERSTATE_H + +#include +#include +#include + +namespace ESM +{ + class ESMReader; + class ESMWriter; + + struct RegionWeatherState + { + int mWeather; + std::vector mChances; + }; + + struct WeatherState + { + std::string mCurrentRegion; + float mTimePassed; + bool mFastForward; + float mWeatherUpdateTime; + float mTransitionFactor; + int mCurrentWeather; + int mNextWeather; + int mQueuedWeather; + std::map mRegions; + + void load(ESMReader& esm); + void save(ESMWriter& esm) const; + }; +} + +#endif diff --git a/components/myguiplatform/myguiloglistener.cpp b/components/myguiplatform/myguiloglistener.cpp index 0ca1af3415..e389f5bf92 100644 --- a/components/myguiplatform/myguiloglistener.cpp +++ b/components/myguiplatform/myguiloglistener.cpp @@ -1,40 +1,40 @@ -#include "myguiloglistener.hpp" - -#include - -#include - -namespace osgMyGUI -{ - void CustomLogListener::open() - { - mStream.open(mFileName, std::ios_base::out); - if (!mStream.is_open()) - Log(Debug::Error) << "Unable to create MyGUI log with path " << mFileName; - } - - void CustomLogListener::close() - { - if (mStream.is_open()) - mStream.close(); - } - - void CustomLogListener::flush() - { - if (mStream.is_open()) - mStream.flush(); - } - - void CustomLogListener::log(const std::string& _section, MyGUI::LogLevel _level, const struct tm* _time, const std::string& _message, const char* _file, int _line) - { - if (mStream.is_open()) - { - const char* separator = " | "; - mStream << std::setw(2) << std::setfill('0') << _time->tm_hour << ":" - << std::setw(2) << std::setfill('0') << _time->tm_min << ":" - << std::setw(2) << std::setfill('0') << _time->tm_sec << separator - << _section << separator << _level.print() << separator - << _message << separator << _file << separator << _line << std::endl; - } - } -} +#include "myguiloglistener.hpp" + +#include + +#include + +namespace osgMyGUI +{ + void CustomLogListener::open() + { + mStream.open(mFileName, std::ios_base::out); + if (!mStream.is_open()) + Log(Debug::Error) << "Unable to create MyGUI log with path " << mFileName; + } + + void CustomLogListener::close() + { + if (mStream.is_open()) + mStream.close(); + } + + void CustomLogListener::flush() + { + if (mStream.is_open()) + mStream.flush(); + } + + void CustomLogListener::log(const std::string& _section, MyGUI::LogLevel _level, const struct tm* _time, const std::string& _message, const char* _file, int _line) + { + if (mStream.is_open()) + { + const char* separator = " | "; + mStream << std::setw(2) << std::setfill('0') << _time->tm_hour << ":" + << std::setw(2) << std::setfill('0') << _time->tm_min << ":" + << std::setw(2) << std::setfill('0') << _time->tm_sec << separator + << _section << separator << _level.print() << separator + << _message << separator << _file << separator << _line << std::endl; + } + } +} diff --git a/components/myguiplatform/myguiloglistener.hpp b/components/myguiplatform/myguiloglistener.hpp index 4d6072a1d6..6379428e00 100644 --- a/components/myguiplatform/myguiloglistener.hpp +++ b/components/myguiplatform/myguiloglistener.hpp @@ -1,68 +1,68 @@ -#ifndef OPENMW_COMPONENTS_MYGUIPLATFORM_LOGLISTENER_H -#define OPENMW_COMPONENTS_MYGUIPLATFORM_LOGLISTENER_H - -#include -#include -#include - -#include -#include -#include -#include - -namespace osgMyGUI -{ - - /// \brief Custom MyGUI::ILogListener interface implementation - /// being able to portably handle UTF-8 encoded path. - /// \todo try patching MyGUI to make this easier - class CustomLogListener : public MyGUI::ILogListener - { - public: - CustomLogListener(const std::filesystem::path &name) - : mFileName(name) - {} - - ~CustomLogListener() {} - - void open() override; - void close() override; - void flush() override; - - void log(const std::string& _section, MyGUI::LogLevel _level, const struct tm* _time, const std::string& _message, const char* _file, int _line) override; - - private: - std::ofstream mStream; - std::filesystem::path mFileName; - }; - - /// \brief Helper class holding data that required during - /// MyGUI log creation - class LogFacility - { - MyGUI::ConsoleLogListener mConsole; - CustomLogListener mFile; - MyGUI::LevelLogFilter mFilter; - MyGUI::LogSource mSource; - - public: - - LogFacility(const std::filesystem::path &output, bool console) - : mFile(output) - { - mConsole.setEnabled(console); - mFilter.setLoggingLevel(MyGUI::LogLevel::Info); - - mSource.addLogListener(&mFile); - mSource.addLogListener(&mConsole); - mSource.setLogFilter(&mFilter); - - mSource.open(); - } - - MyGUI::LogSource *getSource() { return &mSource; } - }; - -} - -#endif +#ifndef OPENMW_COMPONENTS_MYGUIPLATFORM_LOGLISTENER_H +#define OPENMW_COMPONENTS_MYGUIPLATFORM_LOGLISTENER_H + +#include +#include +#include + +#include +#include +#include +#include + +namespace osgMyGUI +{ + + /// \brief Custom MyGUI::ILogListener interface implementation + /// being able to portably handle UTF-8 encoded path. + /// \todo try patching MyGUI to make this easier + class CustomLogListener : public MyGUI::ILogListener + { + public: + CustomLogListener(const std::filesystem::path &name) + : mFileName(name) + {} + + ~CustomLogListener() {} + + void open() override; + void close() override; + void flush() override; + + void log(const std::string& _section, MyGUI::LogLevel _level, const struct tm* _time, const std::string& _message, const char* _file, int _line) override; + + private: + std::ofstream mStream; + std::filesystem::path mFileName; + }; + + /// \brief Helper class holding data that required during + /// MyGUI log creation + class LogFacility + { + MyGUI::ConsoleLogListener mConsole; + CustomLogListener mFile; + MyGUI::LevelLogFilter mFilter; + MyGUI::LogSource mSource; + + public: + + LogFacility(const std::filesystem::path &output, bool console) + : mFile(output) + { + mConsole.setEnabled(console); + mFilter.setLoggingLevel(MyGUI::LogLevel::Info); + + mSource.addLogListener(&mFile); + mSource.addLogListener(&mConsole); + mSource.setLogFilter(&mFilter); + + mSource.open(); + } + + MyGUI::LogSource *getSource() { return &mSource; } + }; + +} + +#endif diff --git a/components/sceneutil/clearcolor.hpp b/components/sceneutil/clearcolor.hpp index e6e6468ecc..1a386548ca 100755 --- a/components/sceneutil/clearcolor.hpp +++ b/components/sceneutil/clearcolor.hpp @@ -1,42 +1,42 @@ -#ifndef OPENMW_COMPONENTS_SCENEUTIL_CLEARCOLOR_H -#define OPENMW_COMPONENTS_SCENEUTIL_CLEARCOLOR_H - -#include -#include - -namespace SceneUtil -{ - class ClearColor : public osg::StateAttribute - { - public: - ClearColor() : mMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) {} - ClearColor(const osg::Vec4f& color, GLbitfield mask) : mColor(color), mMask(mask) {} - - ClearColor(const ClearColor& copy,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) - : osg::StateAttribute(copy,copyop), mColor(copy.mColor), mMask(copy.mMask) {} - - META_StateAttribute(fx, ClearColor, static_cast(100)) - - int compare(const StateAttribute& sa) const override - { - COMPARE_StateAttribute_Types(ClearColor, sa); - - COMPARE_StateAttribute_Parameter(mColor); - COMPARE_StateAttribute_Parameter(mMask); - - return 0; - } - - void apply(osg::State& state) const override - { - glClearColor(mColor[0], mColor[1], mColor[2], mColor[3]); - glClear(mMask); - } - - private: - osg::Vec4f mColor; - GLbitfield mMask; - }; -} - -#endif +#ifndef OPENMW_COMPONENTS_SCENEUTIL_CLEARCOLOR_H +#define OPENMW_COMPONENTS_SCENEUTIL_CLEARCOLOR_H + +#include +#include + +namespace SceneUtil +{ + class ClearColor : public osg::StateAttribute + { + public: + ClearColor() : mMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) {} + ClearColor(const osg::Vec4f& color, GLbitfield mask) : mColor(color), mMask(mask) {} + + ClearColor(const ClearColor& copy,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) + : osg::StateAttribute(copy,copyop), mColor(copy.mColor), mMask(copy.mMask) {} + + META_StateAttribute(fx, ClearColor, static_cast(100)) + + int compare(const StateAttribute& sa) const override + { + COMPARE_StateAttribute_Types(ClearColor, sa); + + COMPARE_StateAttribute_Parameter(mColor); + COMPARE_StateAttribute_Parameter(mMask); + + return 0; + } + + void apply(osg::State& state) const override + { + glClearColor(mColor[0], mColor[1], mColor[2], mColor[3]); + glClear(mMask); + } + + private: + osg::Vec4f mColor; + GLbitfield mMask; + }; +} + +#endif diff --git a/extern/oics/ICSChannel.cpp b/extern/oics/ICSChannel.cpp index 82042d3218..04b04c907f 100644 --- a/extern/oics/ICSChannel.cpp +++ b/extern/oics/ICSChannel.cpp @@ -1,265 +1,265 @@ -/* ------------------------------------------------------- -Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the -Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions of -the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS -OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------- */ - -#include "ICSInputControlSystem.h" - -#define B1(t) (t*t) -#define B2(t) (2*t*(1-t)) -#define B3(t) ((1-t)*(1-t)) - -namespace ICS -{ - Channel::Channel(int number, float initialValue - , float bezierMidPointY, float bezierMidPointX, float symmetricAt, float bezierStep) - : mNumber(number) - , mValue(initialValue) - , mSymmetricAt(symmetricAt) - , mBezierStep(bezierStep) - , mEnabled(true) - { - mBezierMidPoint.x = bezierMidPointX; - mBezierMidPoint.y = bezierMidPointY; - - setBezierFunction(bezierMidPointY, bezierMidPointX, symmetricAt, bezierStep); - } - - void Channel::setEnabled(bool enabled) - { - mEnabled = enabled; - } - - float Channel::getValue() - { - if(mValue == 0 || mValue == 1) - { - return mValue; - } - - assert (!mBezierFunction.empty()); - BezierFunction::iterator it = mBezierFunction.begin(); - //size_t size_minus_1 = mBezierFunction.size() - 1; - BezierFunction::iterator last = mBezierFunction.end(); - --last; - for ( ; it != last ; ) - { - BezierPoint left = (*it); - BezierPoint right = (*(++it)); - - if( (left.x <= mValue) && (right.x > mValue) ) - { - float val = left.y - (left.x - mValue) * (left.y - right.y) / (left.x - right.x); - - return std::max(0.0,std::min(1.0, val)); - } - } - - return -1; - } - - void Channel::setValue(float value) - { - float previousValue = this->getValue(); - - mValue = value; - - if(previousValue != value && mEnabled) - { - notifyListeners(previousValue); - } - } - - void Channel::notifyListeners(float previousValue) - { - std::list::iterator pos = mListeners.begin(); - while (pos != mListeners.end()) - { - (*pos)->channelChanged((Channel*)this, this->getValue(), previousValue); - ++pos; - } - } - - void Channel::addControl(Control* control, Channel::ChannelDirection dir, float percentage) - { - ControlChannelBinderItem ccBinderItem; - ccBinderItem.control = control; - ccBinderItem.direction = dir; - ccBinderItem.percentage = percentage; - - mAttachedControls.push_back(ccBinderItem); - } - - Channel::ControlChannelBinderItem Channel::getAttachedControlBinding(Control* control) - { - for(std::vector::iterator it = mAttachedControls.begin() ; - it != mAttachedControls.end() ; it++) - { - if((*it).control == control) - { - return (*it); - } - } - - ControlChannelBinderItem nullBinderItem; - nullBinderItem.control = NULL; - nullBinderItem.direction = Channel/*::ChannelDirection*/::DIRECT; - nullBinderItem.percentage = 0; - return nullBinderItem; - } - - void Channel::update() - { - if(this->getControlsCount() == 1) - { - ControlChannelBinderItem ccBinderItem = mAttachedControls.back(); - float diff = ccBinderItem.control->getValue() - ccBinderItem.control->getInitialValue(); - - if(ccBinderItem.direction == ICS::Channel::DIRECT) - { - this->setValue(ccBinderItem.control->getInitialValue() + (ccBinderItem.percentage * diff)); - } - else - { - this->setValue(ccBinderItem.control->getInitialValue() - (ccBinderItem.percentage * diff)); - } - } - else - { - float val = 0; - std::vector::const_iterator it; - for(it=mAttachedControls.begin(); it!=mAttachedControls.end(); ++it) - { - ControlChannelBinderItem ccBinderItem = (*it); - float diff = ccBinderItem.control->getValue() - ccBinderItem.control->getInitialValue(); - - if(ccBinderItem.direction == ICS::Channel::DIRECT) - { - val += (ccBinderItem.percentage * diff); - } - else - { - val -= (ccBinderItem.percentage * diff); - } - } - - if(mAttachedControls.size() > 0) - { - this->setValue(mAttachedControls.begin()->control->getInitialValue() + val); - } - } - } - - void Channel::setBezierFunction(float bezierMidPointY, float bezierMidPointX, float symmetricAt, float bezierStep) - { - mBezierMidPoint.x = bezierMidPointX; - mBezierMidPoint.y = bezierMidPointY; - mBezierStep = bezierStep; - mSymmetricAt = symmetricAt; - - mBezierFunction.clear(); - - BezierPoint start; - start.x = 0; - start.y = 0; - - BezierPoint end; - end.x = 1; - end.y = 1; - mBezierFunction.push_front(end); - - FilterInterval interval; - interval.startX = start.x; - interval.startY = start.y; - interval.midX = mBezierMidPoint.x; - interval.midY = mBezierMidPoint.y; - interval.endX = end.x; - interval.endY = end.y; - interval.step = bezierStep; - mIntervals.push_back(interval); - - if(!(mBezierMidPoint.x == 0.5 && mBezierMidPoint.y == 0.5)) - { - float t = mBezierStep; - while(t < 1) - { - BezierPoint p; - p.x = start.x * B1(t) + mBezierMidPoint.x * B2(t) + end.x * B3(t); - p.y = start.y * B1(t) + mBezierMidPoint.y * B2(t) + end.y * B3(t); - mBezierFunction.push_front(p); - - t += mBezierStep; - } - } - - mBezierFunction.push_front(start); - } - - void Channel::addBezierInterval(float startX, float startY, float midX, float midY - , float endX, float endY, float step) - { - FilterInterval interval; - interval.startX = startX; - interval.startY = startY; - interval.midX = midX; - interval.midY = midY; - interval.endX = endX; - interval.endY = endY; - interval.step = step; - mIntervals.push_back(interval); - - float t = 0; - while(t <= 1) - { - BezierPoint p; - p.x = startX * B1(t) + midX * B2(t) + endX * B3(t); - p.y = startY * B1(t) + midY * B2(t) + endY * B3(t); - - BezierFunction::iterator it = mBezierFunction.begin(); - while( it != mBezierFunction.end() ) - { - BezierPoint left = (*it); - BezierPoint right; - ++it; - if( it != mBezierFunction.end() ) - { - right = (*it); - } - else - { - right.x = endX; - right.y = endY; - } - - if(p.x > left.x && p.x < right.x) - { - mBezierFunction.insert(it, p); - break; - } - } - - t += 1.0f / ((endX-startX)/step); - } - } -} +/* ------------------------------------------------------- +Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the +Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions of +the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------- */ + +#include "ICSInputControlSystem.h" + +#define B1(t) (t*t) +#define B2(t) (2*t*(1-t)) +#define B3(t) ((1-t)*(1-t)) + +namespace ICS +{ + Channel::Channel(int number, float initialValue + , float bezierMidPointY, float bezierMidPointX, float symmetricAt, float bezierStep) + : mNumber(number) + , mValue(initialValue) + , mSymmetricAt(symmetricAt) + , mBezierStep(bezierStep) + , mEnabled(true) + { + mBezierMidPoint.x = bezierMidPointX; + mBezierMidPoint.y = bezierMidPointY; + + setBezierFunction(bezierMidPointY, bezierMidPointX, symmetricAt, bezierStep); + } + + void Channel::setEnabled(bool enabled) + { + mEnabled = enabled; + } + + float Channel::getValue() + { + if(mValue == 0 || mValue == 1) + { + return mValue; + } + + assert (!mBezierFunction.empty()); + BezierFunction::iterator it = mBezierFunction.begin(); + //size_t size_minus_1 = mBezierFunction.size() - 1; + BezierFunction::iterator last = mBezierFunction.end(); + --last; + for ( ; it != last ; ) + { + BezierPoint left = (*it); + BezierPoint right = (*(++it)); + + if( (left.x <= mValue) && (right.x > mValue) ) + { + float val = left.y - (left.x - mValue) * (left.y - right.y) / (left.x - right.x); + + return std::max(0.0,std::min(1.0, val)); + } + } + + return -1; + } + + void Channel::setValue(float value) + { + float previousValue = this->getValue(); + + mValue = value; + + if(previousValue != value && mEnabled) + { + notifyListeners(previousValue); + } + } + + void Channel::notifyListeners(float previousValue) + { + std::list::iterator pos = mListeners.begin(); + while (pos != mListeners.end()) + { + (*pos)->channelChanged((Channel*)this, this->getValue(), previousValue); + ++pos; + } + } + + void Channel::addControl(Control* control, Channel::ChannelDirection dir, float percentage) + { + ControlChannelBinderItem ccBinderItem; + ccBinderItem.control = control; + ccBinderItem.direction = dir; + ccBinderItem.percentage = percentage; + + mAttachedControls.push_back(ccBinderItem); + } + + Channel::ControlChannelBinderItem Channel::getAttachedControlBinding(Control* control) + { + for(std::vector::iterator it = mAttachedControls.begin() ; + it != mAttachedControls.end() ; it++) + { + if((*it).control == control) + { + return (*it); + } + } + + ControlChannelBinderItem nullBinderItem; + nullBinderItem.control = NULL; + nullBinderItem.direction = Channel/*::ChannelDirection*/::DIRECT; + nullBinderItem.percentage = 0; + return nullBinderItem; + } + + void Channel::update() + { + if(this->getControlsCount() == 1) + { + ControlChannelBinderItem ccBinderItem = mAttachedControls.back(); + float diff = ccBinderItem.control->getValue() - ccBinderItem.control->getInitialValue(); + + if(ccBinderItem.direction == ICS::Channel::DIRECT) + { + this->setValue(ccBinderItem.control->getInitialValue() + (ccBinderItem.percentage * diff)); + } + else + { + this->setValue(ccBinderItem.control->getInitialValue() - (ccBinderItem.percentage * diff)); + } + } + else + { + float val = 0; + std::vector::const_iterator it; + for(it=mAttachedControls.begin(); it!=mAttachedControls.end(); ++it) + { + ControlChannelBinderItem ccBinderItem = (*it); + float diff = ccBinderItem.control->getValue() - ccBinderItem.control->getInitialValue(); + + if(ccBinderItem.direction == ICS::Channel::DIRECT) + { + val += (ccBinderItem.percentage * diff); + } + else + { + val -= (ccBinderItem.percentage * diff); + } + } + + if(mAttachedControls.size() > 0) + { + this->setValue(mAttachedControls.begin()->control->getInitialValue() + val); + } + } + } + + void Channel::setBezierFunction(float bezierMidPointY, float bezierMidPointX, float symmetricAt, float bezierStep) + { + mBezierMidPoint.x = bezierMidPointX; + mBezierMidPoint.y = bezierMidPointY; + mBezierStep = bezierStep; + mSymmetricAt = symmetricAt; + + mBezierFunction.clear(); + + BezierPoint start; + start.x = 0; + start.y = 0; + + BezierPoint end; + end.x = 1; + end.y = 1; + mBezierFunction.push_front(end); + + FilterInterval interval; + interval.startX = start.x; + interval.startY = start.y; + interval.midX = mBezierMidPoint.x; + interval.midY = mBezierMidPoint.y; + interval.endX = end.x; + interval.endY = end.y; + interval.step = bezierStep; + mIntervals.push_back(interval); + + if(!(mBezierMidPoint.x == 0.5 && mBezierMidPoint.y == 0.5)) + { + float t = mBezierStep; + while(t < 1) + { + BezierPoint p; + p.x = start.x * B1(t) + mBezierMidPoint.x * B2(t) + end.x * B3(t); + p.y = start.y * B1(t) + mBezierMidPoint.y * B2(t) + end.y * B3(t); + mBezierFunction.push_front(p); + + t += mBezierStep; + } + } + + mBezierFunction.push_front(start); + } + + void Channel::addBezierInterval(float startX, float startY, float midX, float midY + , float endX, float endY, float step) + { + FilterInterval interval; + interval.startX = startX; + interval.startY = startY; + interval.midX = midX; + interval.midY = midY; + interval.endX = endX; + interval.endY = endY; + interval.step = step; + mIntervals.push_back(interval); + + float t = 0; + while(t <= 1) + { + BezierPoint p; + p.x = startX * B1(t) + midX * B2(t) + endX * B3(t); + p.y = startY * B1(t) + midY * B2(t) + endY * B3(t); + + BezierFunction::iterator it = mBezierFunction.begin(); + while( it != mBezierFunction.end() ) + { + BezierPoint left = (*it); + BezierPoint right; + ++it; + if( it != mBezierFunction.end() ) + { + right = (*it); + } + else + { + right.x = endX; + right.y = endY; + } + + if(p.x > left.x && p.x < right.x) + { + mBezierFunction.insert(it, p); + break; + } + } + + t += 1.0f / ((endX-startX)/step); + } + } +} diff --git a/extern/oics/ICSChannel.h b/extern/oics/ICSChannel.h index 3da53369c3..17ddc7725f 100644 --- a/extern/oics/ICSChannel.h +++ b/extern/oics/ICSChannel.h @@ -1,126 +1,126 @@ -/* ------------------------------------------------------- -Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the -Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions of -the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS -OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------- */ - -#ifndef OICS_Channel_H_ -#define OICS_Channel_H_ - -#include "ICSPrerequisites.h" - -#include "ICSChannelListener.h" - -namespace ICS -{ - struct FilterInterval{ - //std::string type; //! @todo uncomment when more types implemented - float startX; - float startY; - float midX; - float midY; - float endX; - float endY; - float step; - }; - - typedef std::list IntervalList; - - class DllExport Channel - { - public: - enum ChannelDirection - { - INVERSE = -1, DIRECT = 1 - }; - - typedef struct { - ChannelDirection direction; - float percentage; - Control* control; - } ControlChannelBinderItem; - - - Channel(int number, float initialValue = 0.5 - , float bezierMidPointY = 0.5, float bezierMidPointX = 0.5 - , float symmetricAt = 0, float bezierStep = 0.2); //! @todo implement symetry - ~Channel(){}; - - void setValue(float value); - float getValue(); - - inline int getNumber(){ return mNumber; }; - - void addControl(Control* control, Channel::ChannelDirection dir, float percentage); - inline size_t getControlsCount(){ return mAttachedControls.size(); }; - std::vector getAttachedControls(){ return mAttachedControls; }; - ControlChannelBinderItem getAttachedControlBinding(Control* control); - - void addListener(ChannelListener* ob){ mListeners.push_back(ob); }; - void removeListener(ChannelListener* ob){ mListeners.remove(ob); }; - - void update(); - - void setBezierFunction(float bezierMidPointY, float bezierMidPointX = 0.5 - , float symmetricAt = 0, float bezierStep = 0.2); - - void addBezierInterval(float startX, float startY, float midX, float midY - , float endX, float endY, float step = 0.1); - - IntervalList& getIntervals(){ return mIntervals; }; - - void setEnabled(bool enabled); - - protected: - - int mNumber; - float mValue; - - struct BezierPoint{ - float x; - float y; - bool operator < (const BezierPoint& other){ return x < other.x; } - }; - - typedef std::list BezierFunction; - - BezierPoint mBezierMidPoint; - BezierFunction mBezierFunction; - float mSymmetricAt; - float mBezierStep; - - IntervalList mIntervals; - - std::vector mAttachedControls; - - std::list mListeners; - void notifyListeners(float previousValue); - - bool mEnabled; - - }; - -} - - -#endif +/* ------------------------------------------------------- +Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the +Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions of +the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------- */ + +#ifndef OICS_Channel_H_ +#define OICS_Channel_H_ + +#include "ICSPrerequisites.h" + +#include "ICSChannelListener.h" + +namespace ICS +{ + struct FilterInterval{ + //std::string type; //! @todo uncomment when more types implemented + float startX; + float startY; + float midX; + float midY; + float endX; + float endY; + float step; + }; + + typedef std::list IntervalList; + + class DllExport Channel + { + public: + enum ChannelDirection + { + INVERSE = -1, DIRECT = 1 + }; + + typedef struct { + ChannelDirection direction; + float percentage; + Control* control; + } ControlChannelBinderItem; + + + Channel(int number, float initialValue = 0.5 + , float bezierMidPointY = 0.5, float bezierMidPointX = 0.5 + , float symmetricAt = 0, float bezierStep = 0.2); //! @todo implement symetry + ~Channel(){}; + + void setValue(float value); + float getValue(); + + inline int getNumber(){ return mNumber; }; + + void addControl(Control* control, Channel::ChannelDirection dir, float percentage); + inline size_t getControlsCount(){ return mAttachedControls.size(); }; + std::vector getAttachedControls(){ return mAttachedControls; }; + ControlChannelBinderItem getAttachedControlBinding(Control* control); + + void addListener(ChannelListener* ob){ mListeners.push_back(ob); }; + void removeListener(ChannelListener* ob){ mListeners.remove(ob); }; + + void update(); + + void setBezierFunction(float bezierMidPointY, float bezierMidPointX = 0.5 + , float symmetricAt = 0, float bezierStep = 0.2); + + void addBezierInterval(float startX, float startY, float midX, float midY + , float endX, float endY, float step = 0.1); + + IntervalList& getIntervals(){ return mIntervals; }; + + void setEnabled(bool enabled); + + protected: + + int mNumber; + float mValue; + + struct BezierPoint{ + float x; + float y; + bool operator < (const BezierPoint& other){ return x < other.x; } + }; + + typedef std::list BezierFunction; + + BezierPoint mBezierMidPoint; + BezierFunction mBezierFunction; + float mSymmetricAt; + float mBezierStep; + + IntervalList mIntervals; + + std::vector mAttachedControls; + + std::list mListeners; + void notifyListeners(float previousValue); + + bool mEnabled; + + }; + +} + + +#endif diff --git a/extern/oics/ICSChannelListener.h b/extern/oics/ICSChannelListener.h index 1f50d0e31d..b7f98cefa8 100644 --- a/extern/oics/ICSChannelListener.h +++ b/extern/oics/ICSChannelListener.h @@ -1,48 +1,48 @@ -/* ------------------------------------------------------- -Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the -Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions of -the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS -OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------- */ - -#ifndef _ChannelListener_H_ -#define _ChannelListener_H_ - -#include "ICSPrerequisites.h" - -#include "ICSChannel.h" - -namespace ICS -{ - - class DllExport ChannelListener - { - public: - virtual void channelChanged(Channel* channel, float currentValue, float previousValue) = 0; - - virtual ~ChannelListener() = default; - }; - -} - - -#endif +/* ------------------------------------------------------- +Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the +Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions of +the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------- */ + +#ifndef _ChannelListener_H_ +#define _ChannelListener_H_ + +#include "ICSPrerequisites.h" + +#include "ICSChannel.h" + +namespace ICS +{ + + class DllExport ChannelListener + { + public: + virtual void channelChanged(Channel* channel, float currentValue, float previousValue) = 0; + + virtual ~ChannelListener() = default; + }; + +} + + +#endif diff --git a/extern/oics/ICSControl.cpp b/extern/oics/ICSControl.cpp index 1e9679d1f8..d1fb4b3d59 100644 --- a/extern/oics/ICSControl.cpp +++ b/extern/oics/ICSControl.cpp @@ -1,161 +1,161 @@ -/* ------------------------------------------------------- -Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the -Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions of -the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS -OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------- */ - -#include "ICSInputControlSystem.h" - -#include "ICSControl.h" - -namespace ICS -{ - Control::Control(const std::string& name, bool autoChangeDirectionOnLimitsAfterStop, bool autoReverseToInitialValue - , float initialValue, float stepSize, float stepsPerSeconds, bool axisBindable) - : mValue(initialValue) - , mInitialValue(initialValue) - , mName(name) - , mStepSize(stepSize) - , mStepsPerSeconds(stepsPerSeconds) - , mAutoReverseToInitialValue(autoReverseToInitialValue) - , mIgnoreAutoReverse(false) - , mAutoChangeDirectionOnLimitsAfterStop(autoChangeDirectionOnLimitsAfterStop) - , mAxisBindable(axisBindable) - , currentChangingDirection(STOP) - { - - } - - Control::~Control() - { - mAttachedChannels.clear(); - } - - void Control::setValue(float value) - { - float previousValue = mValue; - - mValue = std::max(0.0,std::min(1.0,value)); - - if(mValue != previousValue) - { - updateChannels(); - - notifyListeners(previousValue); - } - } - - void Control::attachChannel(Channel* channel, Channel::ChannelDirection direction, float percentage) - { - mAttachedChannels.push_back(channel); - channel->addControl(this, direction, percentage); - } - - void Control::updateChannels() - { - std::list::iterator pos = mAttachedChannels.begin(); - while (pos != mAttachedChannels.end()) - { - ((Channel* )(*pos))->update(); - ++pos; - } - } - - void Control::notifyListeners(float previousValue) - { - std::list::iterator pos = mListeners.begin(); - while (pos != mListeners.end()) - { - (*pos)->controlChanged((Control*)this, this->getValue(), previousValue); - ++pos; - } - } - - void Control::setChangingDirection(ControlChangingDirection direction) - { - currentChangingDirection = direction; - mPendingActions.push_back(direction); - } - - void Control::update(float timeSinceLastFrame) - { - if(!mPendingActions.empty()) - { - size_t timedActionsCount = 0; - - std::list::iterator cached_end = mPendingActions.end(); - for(std::list::iterator it = mPendingActions.begin() ; - it != cached_end ; ++it) - { - if( (*it) != Control::STOP ) - { - timedActionsCount++; - } - } - - float timeSinceLastFramePart = timeSinceLastFrame / std::max(1, timedActionsCount); - for(std::list::iterator it = mPendingActions.begin() ; - it != cached_end ; ++it) - { - if( (*it) != Control::STOP ) - { - this->setValue(mValue + - (((int)(*it)) * mStepSize * mStepsPerSeconds * (timeSinceLastFramePart))); - } - else if(mAutoReverseToInitialValue && !mIgnoreAutoReverse && mValue != mInitialValue ) - { - - if(mValue > mInitialValue) - { - this->setValue( std::max( mInitialValue, - mValue - (mStepSize * mStepsPerSeconds * (timeSinceLastFramePart)))); - } - else if(mValue < mInitialValue) - { - this->setValue( std::min( mInitialValue, - mValue + (mStepSize * mStepsPerSeconds * (timeSinceLastFramePart)))); - } - } - } - mPendingActions.clear(); - } - else if( currentChangingDirection != Control::STOP ) - { - this->setValue(mValue + - (((int)currentChangingDirection) * mStepSize * mStepsPerSeconds * (timeSinceLastFrame))); - } - else if(mAutoReverseToInitialValue && !mIgnoreAutoReverse && mValue != mInitialValue ) - { - if(mValue > mInitialValue) - { - this->setValue( std::max( mInitialValue, - mValue - (mStepSize * mStepsPerSeconds * (timeSinceLastFrame)))); - } - else if(mValue < mInitialValue) - { - this->setValue( std::min( mInitialValue, - mValue + (mStepSize * mStepsPerSeconds * (timeSinceLastFrame)))); - } - } - } -} +/* ------------------------------------------------------- +Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the +Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions of +the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------- */ + +#include "ICSInputControlSystem.h" + +#include "ICSControl.h" + +namespace ICS +{ + Control::Control(const std::string& name, bool autoChangeDirectionOnLimitsAfterStop, bool autoReverseToInitialValue + , float initialValue, float stepSize, float stepsPerSeconds, bool axisBindable) + : mValue(initialValue) + , mInitialValue(initialValue) + , mName(name) + , mStepSize(stepSize) + , mStepsPerSeconds(stepsPerSeconds) + , mAutoReverseToInitialValue(autoReverseToInitialValue) + , mIgnoreAutoReverse(false) + , mAutoChangeDirectionOnLimitsAfterStop(autoChangeDirectionOnLimitsAfterStop) + , mAxisBindable(axisBindable) + , currentChangingDirection(STOP) + { + + } + + Control::~Control() + { + mAttachedChannels.clear(); + } + + void Control::setValue(float value) + { + float previousValue = mValue; + + mValue = std::max(0.0,std::min(1.0,value)); + + if(mValue != previousValue) + { + updateChannels(); + + notifyListeners(previousValue); + } + } + + void Control::attachChannel(Channel* channel, Channel::ChannelDirection direction, float percentage) + { + mAttachedChannels.push_back(channel); + channel->addControl(this, direction, percentage); + } + + void Control::updateChannels() + { + std::list::iterator pos = mAttachedChannels.begin(); + while (pos != mAttachedChannels.end()) + { + ((Channel* )(*pos))->update(); + ++pos; + } + } + + void Control::notifyListeners(float previousValue) + { + std::list::iterator pos = mListeners.begin(); + while (pos != mListeners.end()) + { + (*pos)->controlChanged((Control*)this, this->getValue(), previousValue); + ++pos; + } + } + + void Control::setChangingDirection(ControlChangingDirection direction) + { + currentChangingDirection = direction; + mPendingActions.push_back(direction); + } + + void Control::update(float timeSinceLastFrame) + { + if(!mPendingActions.empty()) + { + size_t timedActionsCount = 0; + + std::list::iterator cached_end = mPendingActions.end(); + for(std::list::iterator it = mPendingActions.begin() ; + it != cached_end ; ++it) + { + if( (*it) != Control::STOP ) + { + timedActionsCount++; + } + } + + float timeSinceLastFramePart = timeSinceLastFrame / std::max(1, timedActionsCount); + for(std::list::iterator it = mPendingActions.begin() ; + it != cached_end ; ++it) + { + if( (*it) != Control::STOP ) + { + this->setValue(mValue + + (((int)(*it)) * mStepSize * mStepsPerSeconds * (timeSinceLastFramePart))); + } + else if(mAutoReverseToInitialValue && !mIgnoreAutoReverse && mValue != mInitialValue ) + { + + if(mValue > mInitialValue) + { + this->setValue( std::max( mInitialValue, + mValue - (mStepSize * mStepsPerSeconds * (timeSinceLastFramePart)))); + } + else if(mValue < mInitialValue) + { + this->setValue( std::min( mInitialValue, + mValue + (mStepSize * mStepsPerSeconds * (timeSinceLastFramePart)))); + } + } + } + mPendingActions.clear(); + } + else if( currentChangingDirection != Control::STOP ) + { + this->setValue(mValue + + (((int)currentChangingDirection) * mStepSize * mStepsPerSeconds * (timeSinceLastFrame))); + } + else if(mAutoReverseToInitialValue && !mIgnoreAutoReverse && mValue != mInitialValue ) + { + if(mValue > mInitialValue) + { + this->setValue( std::max( mInitialValue, + mValue - (mStepSize * mStepsPerSeconds * (timeSinceLastFrame)))); + } + else if(mValue < mInitialValue) + { + this->setValue( std::min( mInitialValue, + mValue + (mStepSize * mStepsPerSeconds * (timeSinceLastFrame)))); + } + } + } +} diff --git a/extern/oics/ICSControl.h b/extern/oics/ICSControl.h index 1ed4376524..f62e2594f5 100644 --- a/extern/oics/ICSControl.h +++ b/extern/oics/ICSControl.h @@ -1,108 +1,108 @@ -/* ------------------------------------------------------- -Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the -Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions of -the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS -OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------- */ - -#ifndef OICS_Control_H_ -#define OICS_Control_H_ - -#include "ICSPrerequisites.h" - -#include "ICSChannel.h" -#include "ICSControlListener.h" - -namespace ICS -{ - - class DllExport Control - { - public: - - enum ControlChangingDirection - { - DECREASE = -1, STOP = 0, INCREASE = 1 - }; - - Control(const std::string& name, bool autoChangeDirectionOnLimitsAfterStop = false, bool autoReverseToInitialValue = false, float initialValue = 0.5, float stepSize = 0.1, float stepsPerSeconds = 2.0, bool axisBindable = true); - ~Control(); - - void setChangingDirection(ControlChangingDirection direction); - inline ControlChangingDirection getChangingDirection(){ return currentChangingDirection; }; - - void setValue(float value); - inline float getValue(){ return mValue; }; +/* ------------------------------------------------------- +Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the +Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions of +the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------- */ + +#ifndef OICS_Control_H_ +#define OICS_Control_H_ + +#include "ICSPrerequisites.h" + +#include "ICSChannel.h" +#include "ICSControlListener.h" + +namespace ICS +{ + + class DllExport Control + { + public: + + enum ControlChangingDirection + { + DECREASE = -1, STOP = 0, INCREASE = 1 + }; + + Control(const std::string& name, bool autoChangeDirectionOnLimitsAfterStop = false, bool autoReverseToInitialValue = false, float initialValue = 0.5, float stepSize = 0.1, float stepsPerSeconds = 2.0, bool axisBindable = true); + ~Control(); + + void setChangingDirection(ControlChangingDirection direction); + inline ControlChangingDirection getChangingDirection(){ return currentChangingDirection; }; + + void setValue(float value); + inline float getValue(){ return mValue; }; inline float getInitialValue(){ return mInitialValue; }; - inline void setInitialValue(float i) {mInitialValue = i;}; - - void attachChannel(Channel* channel, Channel::ChannelDirection direction, float percentage = 1.0); - std::list getAttachedChannels(){ return mAttachedChannels; }; - - inline float getStepSize(){ return mStepSize; }; - inline float getStepsPerSeconds(){ return mStepsPerSeconds; }; - - inline void setIgnoreAutoReverse(bool value){ mIgnoreAutoReverse = value; }; // mouse disable autoreverse - inline bool isAutoReverseIgnored(){ return mIgnoreAutoReverse; }; - inline bool getAutoReverse(){ return mAutoReverseToInitialValue; }; - - inline bool getAutoChangeDirectionOnLimitsAfterStop(){ return mAutoChangeDirectionOnLimitsAfterStop; }; - - inline std::string getName(){ return mName; }; - - inline bool isAxisBindable(){ return mAxisBindable; }; - inline void setAxisBindable(bool value){ mAxisBindable = value; }; - - inline void addListener(ControlListener* ob){ mListeners.push_back(ob); }; - inline void removeListener(ControlListener* ob){ mListeners.remove(ob); }; - - void update(float timeSinceLastFrame); - - protected: - float mValue; - float mInitialValue; - std::string mName; - float mStepSize; - float mStepsPerSeconds; - bool mAutoReverseToInitialValue; - bool mIgnoreAutoReverse; - bool mAutoChangeDirectionOnLimitsAfterStop; - bool mAxisBindable; - - Control::ControlChangingDirection currentChangingDirection; - std::list mAttachedChannels; - - std::list mListeners; - - std::list mPendingActions; - - protected: - - void updateChannels(); - void notifyListeners(float previousValue); - - }; - -} - - -#endif + inline void setInitialValue(float i) {mInitialValue = i;}; + + void attachChannel(Channel* channel, Channel::ChannelDirection direction, float percentage = 1.0); + std::list getAttachedChannels(){ return mAttachedChannels; }; + + inline float getStepSize(){ return mStepSize; }; + inline float getStepsPerSeconds(){ return mStepsPerSeconds; }; + + inline void setIgnoreAutoReverse(bool value){ mIgnoreAutoReverse = value; }; // mouse disable autoreverse + inline bool isAutoReverseIgnored(){ return mIgnoreAutoReverse; }; + inline bool getAutoReverse(){ return mAutoReverseToInitialValue; }; + + inline bool getAutoChangeDirectionOnLimitsAfterStop(){ return mAutoChangeDirectionOnLimitsAfterStop; }; + + inline std::string getName(){ return mName; }; + + inline bool isAxisBindable(){ return mAxisBindable; }; + inline void setAxisBindable(bool value){ mAxisBindable = value; }; + + inline void addListener(ControlListener* ob){ mListeners.push_back(ob); }; + inline void removeListener(ControlListener* ob){ mListeners.remove(ob); }; + + void update(float timeSinceLastFrame); + + protected: + float mValue; + float mInitialValue; + std::string mName; + float mStepSize; + float mStepsPerSeconds; + bool mAutoReverseToInitialValue; + bool mIgnoreAutoReverse; + bool mAutoChangeDirectionOnLimitsAfterStop; + bool mAxisBindable; + + Control::ControlChangingDirection currentChangingDirection; + std::list mAttachedChannels; + + std::list mListeners; + + std::list mPendingActions; + + protected: + + void updateChannels(); + void notifyListeners(float previousValue); + + }; + +} + + +#endif diff --git a/extern/oics/ICSControlListener.h b/extern/oics/ICSControlListener.h index 73fd06cb15..ed1b619f12 100644 --- a/extern/oics/ICSControlListener.h +++ b/extern/oics/ICSControlListener.h @@ -1,48 +1,48 @@ -/* ------------------------------------------------------- -Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the -Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions of -the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS -OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------- */ - -#ifndef _ControlListener_H_ -#define _ControlListener_H_ - -#include "ICSPrerequisites.h" - -#include "ICSControl.h" - -namespace ICS -{ - - class DllExport ControlListener - { - public: - virtual void controlChanged(Control* control, float currentValue, float previousValue) = 0; - - virtual ~ControlListener() = default; - }; - -} - - -#endif +/* ------------------------------------------------------- +Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the +Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions of +the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------- */ + +#ifndef _ControlListener_H_ +#define _ControlListener_H_ + +#include "ICSPrerequisites.h" + +#include "ICSControl.h" + +namespace ICS +{ + + class DllExport ControlListener + { + public: + virtual void controlChanged(Control* control, float currentValue, float previousValue) = 0; + + virtual ~ControlListener() = default; + }; + +} + + +#endif diff --git a/extern/oics/ICSInputControlSystem.cpp b/extern/oics/ICSInputControlSystem.cpp index c03c039a40..9f03ec121e 100644 --- a/extern/oics/ICSInputControlSystem.cpp +++ b/extern/oics/ICSInputControlSystem.cpp @@ -1,817 +1,817 @@ -/* ------------------------------------------------------- -Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the -Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions of -the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS -OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------- */ - -#include "ICSInputControlSystem.h" - -namespace ICS -{ - const float ICS_MAX = std::numeric_limits::max(); - - InputControlSystem::InputControlSystem(std::string file, bool active - , DetectingBindingListener* detectingBindingListener - , InputControlSystemLog* log, size_t channelCount) - : mFileName(file) - , mDeadZone(0.1f) - , mLog(log) - , mDetectingBindingListener(detectingBindingListener) - , mDetectingBindingControl(NULL) - , mDetectingBindingDirection(Control::STOP) - , mXmouseAxisBinded(false), mYmouseAxisBinded(false) - , mClientWidth(1) - , mClientHeight(1) - { - ICS_LOG(" - Creating InputControlSystem - "); - - this->mActive = active; - - ICS_LOG("Channel count = " + ToString(channelCount) ); - for(size_t i=0;iLoadFile(); - - if(xmlDoc->Error()) - { - std::ostringstream message; - message << "TinyXml reported an error reading \""+ file + "\". Row " << - (int)xmlDoc->ErrorRow() << ", Col " << (int)xmlDoc->ErrorCol() << ": " << - xmlDoc->ErrorDesc() ; - ICS_LOG(message.str()); - - delete xmlDoc; - return; - } - - xmlRoot = xmlDoc->RootElement(); - if(std::string(xmlRoot->Value()) != "Controller") { - ICS_LOG("Error: Invalid Controller file. Missing element."); - delete xmlDoc; - return; - } - - TiXmlElement* xmlControl = xmlRoot->FirstChildElement("Control"); - - size_t controlChannelCount = 0; - while(xmlControl) - { - TiXmlElement* xmlChannel = xmlControl->FirstChildElement("Channel"); - while(xmlChannel) - { - controlChannelCount = std::max(channelCount, FromString(xmlChannel->Attribute("number"))+1); - - xmlChannel = xmlChannel->NextSiblingElement("Channel"); - } - - xmlControl = xmlControl->NextSiblingElement("Control"); - } - - static const size_t channelsCountLimit = 65536; - if (controlChannelCount > channelsCountLimit) - { - ICS_LOG("Warning: requested channels count (" + ToString(controlChannelCount) + ") exceeds allowed maximum (" + ToString(channelsCountLimit) + "), clamping it"); - controlChannelCount = channelsCountLimit; - } - - if(controlChannelCount > channelCount) - { - size_t dif = controlChannelCount - channelCount; - ICS_LOG("Warning: default channel count exceeded. Adding " + ToString(dif) + " channels" ); - for(size_t i = channelCount ; i < controlChannelCount ; i++) - { - mChannels.push_back(new Channel((int)i)); - } - } - - ICS_LOG("Applying filters to channels"); - // - // - // - // - - TiXmlElement* xmlChannelFilter = xmlRoot->FirstChildElement("ChannelFilter"); - while(xmlChannelFilter) - { - size_t ch = FromString(xmlChannelFilter->Attribute("number")); - if(ch >= controlChannelCount) - { - ICS_LOG("ERROR: channel number (ch) is out of range"); - xmlChannelFilter = xmlChannelFilter->NextSiblingElement("ChannelFilter"); - continue; - } - - TiXmlElement* xmlInterval = xmlChannelFilter->FirstChildElement("Interval"); - while(xmlInterval) - { - std::string type = xmlInterval->Attribute("type"); - - if(type == "bezier") - { - float startX = FromString(xmlInterval->Attribute("startX")); - float startY = FromString(xmlInterval->Attribute("startY")); - float midX = FromString(xmlInterval->Attribute("midX")); - float midY = FromString(xmlInterval->Attribute("midY")); - float endX = FromString(xmlInterval->Attribute("endX")); - float endY = FromString(xmlInterval->Attribute("endY")); - - float step = FromString(xmlInterval->Attribute("step")); - - ICS_LOG("Applying Bezier filter to channel [number=" - + ToString(ch) + ", startX=" - + ToString(startX) + ", startY=" - + ToString(startY) + ", midX=" - + ToString(midX) + ", midY=" - + ToString(midY) + ", endX=" - + ToString(endX) + ", endY=" - + ToString(endY) + ", step=" - + ToString(step) + "]"); - - mChannels.at(ch)->addBezierInterval(startX, startY, midX, midY, endX, endY, step); - } - - xmlInterval = xmlInterval->NextSiblingElement("Interval"); - } - - xmlChannelFilter = xmlChannelFilter->NextSiblingElement("ChannelFilter"); - } - - xmlControl = xmlRoot->FirstChildElement("Control"); - while(xmlControl) - { - bool axisBindable = true; - if(xmlControl->Attribute("axisBindable")) - { - axisBindable = (std::string( xmlControl->Attribute("axisBindable") ) == "true"); - } - - ICS_LOG("Adding Control [name=" - + std::string( xmlControl->Attribute("name") ) + ", autoChangeDirectionOnLimitsAfterStop=" - + std::string( xmlControl->Attribute("autoChangeDirectionOnLimitsAfterStop") ) + ", autoReverseToInitialValue=" - + std::string( xmlControl->Attribute("autoReverseToInitialValue") ) + ", initialValue=" - + std::string( xmlControl->Attribute("initialValue") ) + ", stepSize=" - + std::string( xmlControl->Attribute("stepSize") ) + ", stepsPerSeconds=" - + std::string( xmlControl->Attribute("stepsPerSeconds") ) + ", axisBindable=" - + std::string( (axisBindable)? "true" : "false" ) + "]"); - - float _stepSize = 0; - if(xmlControl->Attribute("stepSize")) - { - std::string value(xmlControl->Attribute("stepSize")); - if(value == "MAX") - { - _stepSize = ICS_MAX; - } - else - { - _stepSize = FromString(value.c_str()); - } - } - else - { - ICS_LOG("Warning: no stepSize value found. Default value is 0."); - } - - float _stepsPerSeconds = 0; - if(xmlControl->Attribute("stepsPerSeconds")) - { - std::string value(xmlControl->Attribute("stepsPerSeconds")); - if(value == "MAX") - { - _stepsPerSeconds = ICS_MAX; - } - else - { - _stepsPerSeconds = FromString(value.c_str()); - } - } - else - { - ICS_LOG("Warning: no stepSize value found. Default value is 0."); - } - - addControl( new Control(xmlControl->Attribute("name") - , std::string( xmlControl->Attribute("autoChangeDirectionOnLimitsAfterStop") ) == "true" - , std::string( xmlControl->Attribute("autoReverseToInitialValue") ) == "true" - , FromString(xmlControl->Attribute("initialValue")) - , _stepSize - , _stepsPerSeconds - , axisBindable) ); - - loadKeyBinders(xmlControl); - - loadMouseAxisBinders(xmlControl); - - loadMouseButtonBinders(xmlControl); - - loadJoystickAxisBinders(xmlControl); - - loadJoystickButtonBinders(xmlControl); - - /* ---------------------------------------------------------------------------------------- - * OPENMW CODE STARTS HERE - * Mouse Wheel support added by Michael Stopa (Stomy) */ - - loadMouseWheelBinders(xmlControl); - - /* OPENMW CODE ENDS HERE - * ------------------------------------------------------------------------------------- */ - - // Attach controls to channels - TiXmlElement* xmlChannel = xmlControl->FirstChildElement("Channel"); - while(xmlChannel) - { - ICS_LOG("\tAttaching control to channel [number=" - + std::string( xmlChannel->Attribute("number") ) + ", direction=" - + std::string( xmlChannel->Attribute("direction") ) + "]"); - - float percentage = 1; - if(xmlChannel->Attribute("percentage")) - { - if(StringIsNumber(xmlChannel->Attribute("percentage"))) - { - float val = FromString(xmlChannel->Attribute("percentage")); - if(val > 1 || val < 0) - { - ICS_LOG("ERROR: attaching percentage value range is [0,1]"); - } - else - { - percentage = val; - } - } - else - { - ICS_LOG("ERROR: attaching percentage value range is [0,1]"); - } - } - - size_t chNumber = FromString(xmlChannel->Attribute("number")); - if(chNumber >= controlChannelCount) - { - ICS_LOG("ERROR: channel number (chNumber) is out of range"); - } - else - { - if(std::string(xmlChannel->Attribute("direction")) == "DIRECT") - { - mControls.back()->attachChannel(mChannels[ chNumber ],Channel::DIRECT, percentage); - } - else if(std::string(xmlChannel->Attribute("direction")) == "INVERSE") - { - mControls.back()->attachChannel(mChannels[ chNumber ],Channel::INVERSE, percentage); - } - } - - xmlChannel = xmlChannel->NextSiblingElement("Channel"); - } - - xmlControl = xmlControl->NextSiblingElement("Control"); - } - - std::vector::const_iterator o; - for(o = mChannels.begin(); o != mChannels.end(); ++o) - { - (*o)->update(); - } - - delete xmlDoc; - } - - ICS_LOG(" - InputControlSystem Created - "); - } - - InputControlSystem::~InputControlSystem() - { - ICS_LOG(" - Deleting InputControlSystem (" + mFileName + ") - "); - - mJoystickIDList.clear(); - - std::vector::const_iterator o; - for(o = mChannels.begin(); o != mChannels.end(); ++o) - { - delete (*o); - } - mChannels.clear(); - - std::vector::const_iterator o2; - for(o2 = mControls.begin(); o2 != mControls.end(); ++o2) - { - delete (*o2); - } - mControls.clear(); - - mControlsKeyBinderMap.clear(); - mControlsMouseButtonBinderMap.clear(); - mControlsJoystickButtonBinderMap.clear(); - - /* ---------------------------------------------------------------------------------------- - * OPENMW CODE STARTS HERE - * Mouse Wheel support added by Michael Stopa (Stomy) */ - - mControlsMouseWheelBinderMap.clear(); - - /* OPENMW CODE ENDS HERE - * ------------------------------------------------------------------------------------- */ - - ICS_LOG(" - InputControlSystem deleted - "); - } - - std::string InputControlSystem::getBaseFileName() - { - size_t found = mFileName.find_last_of("/\\"); - std::string file = mFileName.substr(found+1); - - return file.substr(0, file.find_last_of(".")); - } - - bool InputControlSystem::save(std::string fileName) - { - if(fileName != "") - { - mFileName = fileName; - } - - TiXmlDocument doc( mFileName.c_str() ); - - TiXmlDeclaration dec; - dec.Parse( "", 0, TIXML_ENCODING_UNKNOWN ); - doc.InsertEndChild(dec); - - TiXmlElement Controller( "Controller" ); - - for(std::vector::const_iterator o = mChannels.begin() ; o != mChannels.end(); ++o) - { - ICS::IntervalList intervals = (*o)->getIntervals(); - - if(intervals.size() > 1) // all channels have a default linear filter - { - TiXmlElement ChannelFilter( "ChannelFilter" ); - - ChannelFilter.SetAttribute("number", ToString((*o)->getNumber()).c_str()); - - ICS::IntervalList::const_iterator interval = intervals.begin(); - while( interval != intervals.end() ) - { - // if not default linear filter - if(!( interval->step == 0.2f - && interval->startX == 0.0f - && interval->startY == 0.0f - && interval->midX == 0.5f - && interval->midY == 0.5f - && interval->endX == 1.0f - && interval->endY == 1.0f )) - { - TiXmlElement XMLInterval( "Interval" ); - - XMLInterval.SetAttribute("type", "bezier"); - XMLInterval.SetAttribute("step", ToString(interval->step).c_str()); - - XMLInterval.SetAttribute("startX", ToString(interval->startX).c_str()); - XMLInterval.SetAttribute("startY", ToString(interval->startY).c_str()); - XMLInterval.SetAttribute("midX", ToString(interval->midX).c_str()); - XMLInterval.SetAttribute("midY", ToString(interval->midY).c_str()); - XMLInterval.SetAttribute("endX", ToString(interval->endX).c_str()); - XMLInterval.SetAttribute("endY", ToString(interval->endY).c_str()); - - ChannelFilter.InsertEndChild(XMLInterval); - } - - ++interval; - } - - Controller.InsertEndChild(ChannelFilter); - } - } - - for(std::vector::const_iterator o = mControls.begin() ; o != mControls.end(); ++o) - { - TiXmlElement control( "Control" ); - - control.SetAttribute( "name", (*o)->getName().c_str() ); - if((*o)->getAutoChangeDirectionOnLimitsAfterStop()) - { - control.SetAttribute( "autoChangeDirectionOnLimitsAfterStop", "true" ); - } - else - { - control.SetAttribute( "autoChangeDirectionOnLimitsAfterStop", "false" ); - } - if((*o)->getAutoReverse()) - { - control.SetAttribute( "autoReverseToInitialValue", "true" ); - } - else - { - control.SetAttribute( "autoReverseToInitialValue", "false" ); - } - control.SetAttribute( "initialValue", ToString((*o)->getInitialValue()).c_str() ); - - if((*o)->getStepSize() == ICS_MAX) - { - control.SetAttribute( "stepSize", "MAX" ); - } - else - { - control.SetAttribute( "stepSize", ToString((*o)->getStepSize()).c_str() ); - } - - if((*o)->getStepsPerSeconds() == ICS_MAX) - { - control.SetAttribute( "stepsPerSeconds", "MAX" ); - } - else - { - control.SetAttribute( "stepsPerSeconds", ToString((*o)->getStepsPerSeconds()).c_str() ); - } - - if(!(*o)->isAxisBindable()) - { - control.SetAttribute( "axisBindable", "false" ); - } - - if(getKeyBinding(*o, Control/*::ControlChangingDirection*/::INCREASE) != SDL_SCANCODE_UNKNOWN) - { - TiXmlElement keyBinder( "KeyBinder" ); - - keyBinder.SetAttribute( "key", ToString( - getKeyBinding(*o, Control/*::ControlChangingDirection*/::INCREASE)).c_str() ); - keyBinder.SetAttribute( "direction", "INCREASE" ); - control.InsertEndChild(keyBinder); - } - - if(getKeyBinding(*o, Control/*::ControlChangingDirection*/::DECREASE) != SDL_SCANCODE_UNKNOWN) - { - TiXmlElement keyBinder( "KeyBinder" ); - - keyBinder.SetAttribute( "key", ToString( - getKeyBinding(*o, Control/*::ControlChangingDirection*/::DECREASE)).c_str() ); - keyBinder.SetAttribute( "direction", "DECREASE" ); - control.InsertEndChild(keyBinder); - } - - if(getMouseAxisBinding(*o, Control/*::ControlChangingDirection*/::INCREASE) - != InputControlSystem/*::NamedAxis*/::UNASSIGNED) - { - TiXmlElement binder( "MouseBinder" ); - - InputControlSystem::NamedAxis axis = - getMouseAxisBinding(*o, Control/*::ControlChangingDirection*/::INCREASE); - if(axis == InputControlSystem/*::NamedAxis*/::X) - { - binder.SetAttribute( "axis", "X" ); - } - else if(axis == InputControlSystem/*::NamedAxis*/::Y) - { - binder.SetAttribute( "axis", "Y" ); - } - else if(axis == InputControlSystem/*::NamedAxis*/::Z) - { - binder.SetAttribute( "axis", "Z" ); - } - - binder.SetAttribute( "direction", "INCREASE" ); - control.InsertEndChild(binder); - } - - if(getMouseAxisBinding(*o, Control/*::ControlChangingDirection*/::DECREASE) - != InputControlSystem/*::NamedAxis*/::UNASSIGNED) - { - TiXmlElement binder( "MouseBinder" ); - - InputControlSystem::NamedAxis axis = - getMouseAxisBinding(*o, Control/*::ControlChangingDirection*/::DECREASE); - if(axis == InputControlSystem/*::NamedAxis*/::X) - { - binder.SetAttribute( "axis", "X" ); - } - else if(axis == InputControlSystem/*::NamedAxis*/::Y) - { - binder.SetAttribute( "axis", "Y" ); - } - else if(axis == InputControlSystem/*::NamedAxis*/::Z) - { - binder.SetAttribute( "axis", "Z" ); - } - - binder.SetAttribute( "direction", "DECREASE" ); - control.InsertEndChild(binder); - } - - /* ---------------------------------------------------------------------------------------- - * OPENMW CODE STARTS HERE - * Mouse Wheel support added by Stomy */ - - if(getMouseWheelBinding(*o, Control::INCREASE) != MouseWheelClick::UNASSIGNED) - { - TiXmlElement binder( "MouseWheelBinder" ); - MouseWheelClick click = getMouseWheelBinding(*o, Control::INCREASE); - bool skip = false; - switch (click) { - case MouseWheelClick::UP: { - binder.SetAttribute("button", "UP"); - } break; - case MouseWheelClick::DOWN: { - binder.SetAttribute("button", "DOWN"); - } break; - case MouseWheelClick::RIGHT: { - binder.SetAttribute("button", "RIGHT"); - } break; - case MouseWheelClick::LEFT: { - binder.SetAttribute("button", "LEFT"); - } break; - default: { - skip = true; - } break; - } - binder.SetAttribute( "direction", "INCREASE" ); - if (!skip) - control.InsertEndChild(binder); - } - - if(getMouseWheelBinding(*o, Control::DECREASE) != MouseWheelClick::UNASSIGNED) - { - TiXmlElement binder( "MouseWheelBinder" ); - MouseWheelClick click = getMouseWheelBinding(*o, Control::INCREASE); - bool skip = false; - switch (click) { - case MouseWheelClick::UP: { - binder.SetAttribute("button", "UP"); - } break; - case MouseWheelClick::DOWN: { - binder.SetAttribute("button", "DOWN"); - } break; - case MouseWheelClick::RIGHT: { - binder.SetAttribute("button", "RIGHT"); - } break; - case MouseWheelClick::LEFT: { - binder.SetAttribute("button", "LEFT"); - } break; - default: { - skip = true; - } break; - } - binder.SetAttribute( "direction", "DECREASE" ); - if (!skip) - control.InsertEndChild(binder); - } - - /* OPENMW CODE ENDS HERE - * ------------------------------------------------------------------------------------- */ - - if(getMouseButtonBinding(*o, Control/*::ControlChangingDirection*/::INCREASE) - != ICS_MAX_DEVICE_BUTTONS) - { - TiXmlElement binder( "MouseButtonBinder" ); - - unsigned int button = getMouseButtonBinding(*o, Control/*::ControlChangingDirection*/::INCREASE); - if(button == SDL_BUTTON_LEFT) - { - binder.SetAttribute( "button", "LEFT" ); - } - else if(button == SDL_BUTTON_MIDDLE) - { - binder.SetAttribute( "button", "MIDDLE" ); - } - else if(button == SDL_BUTTON_RIGHT) - { - binder.SetAttribute( "button", "RIGHT" ); - } - else - { - binder.SetAttribute( "button", ToString(button).c_str() ); - } - binder.SetAttribute( "direction", "INCREASE" ); - control.InsertEndChild(binder); - } - - if(getMouseButtonBinding(*o, Control/*::ControlChangingDirection*/::DECREASE) - != ICS_MAX_DEVICE_BUTTONS) - { - TiXmlElement binder( "MouseButtonBinder" ); - - unsigned int button = getMouseButtonBinding(*o, Control/*::ControlChangingDirection*/::DECREASE); - if(button == SDL_BUTTON_LEFT) - { - binder.SetAttribute( "button", "LEFT" ); - } - else if(button == SDL_BUTTON_MIDDLE) - { - binder.SetAttribute( "button", "MIDDLE" ); - } - else if(button == SDL_BUTTON_RIGHT) - { - binder.SetAttribute( "button", "RIGHT" ); - } - else - { - binder.SetAttribute( "button", ToString(button).c_str() ); - } - binder.SetAttribute( "direction", "DECREASE" ); - control.InsertEndChild(binder); - } - JoystickIDList::const_iterator it = mJoystickIDList.begin(); - while(it!=mJoystickIDList.end()) - { - int deviceID = *it; - if(getJoystickAxisBinding(*o, deviceID, Control/*::ControlChangingDirection*/::INCREASE) - != /*NamedAxis::*/UNASSIGNED) - { - TiXmlElement binder( "JoystickAxisBinder" ); - - binder.SetAttribute( "axis", ToString( - getJoystickAxisBinding(*o, deviceID, Control/*::ControlChangingDirection*/::INCREASE)).c_str() ); - - binder.SetAttribute( "direction", "INCREASE" ); - - binder.SetAttribute( "deviceId", deviceID ); //completely useless, but required for backwards compatability - - control.InsertEndChild(binder); - } - - if(getJoystickAxisBinding(*o, deviceID, Control/*::ControlChangingDirection*/::DECREASE) - != /*NamedAxis::*/UNASSIGNED) - { - TiXmlElement binder( "JoystickAxisBinder" ); - - binder.SetAttribute( "axis", ToString( - getJoystickAxisBinding(*o, deviceID, Control/*::ControlChangingDirection*/::DECREASE)).c_str() ); - - binder.SetAttribute( "direction", "DECREASE" ); - - binder.SetAttribute( "deviceId", deviceID ); //completely useless, but required for backwards compatability - - control.InsertEndChild(binder); - } - - if(getJoystickButtonBinding(*o, deviceID, Control/*::ControlChangingDirection*/::INCREASE) - != ICS_MAX_DEVICE_BUTTONS) - { - TiXmlElement binder( "JoystickButtonBinder" ); - - binder.SetAttribute( "button", ToString( - getJoystickButtonBinding(*o, deviceID, Control/*::ControlChangingDirection*/::INCREASE)).c_str() ); - - binder.SetAttribute( "direction", "INCREASE" ); - - binder.SetAttribute( "deviceId", deviceID ); //completely useless, but required for backwards compatability - - control.InsertEndChild(binder); - } - - if(getJoystickButtonBinding(*o, deviceID, Control/*::ControlChangingDirection*/::DECREASE) - != ICS_MAX_DEVICE_BUTTONS) - { - TiXmlElement binder( "JoystickButtonBinder" ); - - binder.SetAttribute( "button", ToString( - getJoystickButtonBinding(*o, deviceID, Control/*::ControlChangingDirection*/::DECREASE)).c_str() ); - - binder.SetAttribute( "direction", "DECREASE" ); - - binder.SetAttribute( "deviceId", deviceID ); //completely useless, but required for backwards compatability - - control.InsertEndChild(binder); - } - it++; - } - - - std::list channels = (*o)->getAttachedChannels(); - for(std::list::iterator it = channels.begin() ; - it != channels.end() ; ++it) - { - TiXmlElement binder( "Channel" ); - - binder.SetAttribute( "number", ToString((*it)->getNumber()).c_str() ); - - Channel::ChannelDirection direction = (*it)->getAttachedControlBinding(*o).direction; - if(direction == Channel/*::ChannelDirection*/::DIRECT) - { - binder.SetAttribute( "direction", "DIRECT" ); - } - else - { - binder.SetAttribute( "direction", "INVERSE" ); - } - - float percentage = (*it)->getAttachedControlBinding(*o).percentage; - binder.SetAttribute( "percentage", ToString(percentage).c_str() ); - - control.InsertEndChild(binder); - } - - Controller.InsertEndChild(control); - } - - doc.InsertEndChild(Controller); - return doc.SaveFile(); - } - - void InputControlSystem::update(float lTimeSinceLastFrame) - { - if(mActive) - { - std::vector::const_iterator it; - for(it=mControls.begin(); it!=mControls.end(); ++it) - { - (*it)->update(lTimeSinceLastFrame); - } - } - - //! @todo Future versions should consider channel exponentials and mixtures, so - // after updating Controls, Channels should be updated according to their values - } - - float InputControlSystem::getChannelValue(int i) - { - return std::max(0.0,std::min(1.0,mChannels[i]->getValue())); - } - - float InputControlSystem::getControlValue(int i) - { - return mControls[i]->getValue(); - } - - Control* InputControlSystem::findControl(std::string name) - { - if(mActive) - { - std::vector::const_iterator it; - for(it = mControls.begin(); it != mControls.end(); ++it) - { - if( ((Control*)(*it))->getName() == name) - { - return (Control*)(*it); - } - } - } - - return NULL; - } - - void InputControlSystem::enableDetectingBindingState(Control* control - , Control::ControlChangingDirection direction) - { - mDetectingBindingControl = control; - mDetectingBindingDirection = direction; - - mMouseAxisBindingInitialValues[0] = ICS_MOUSE_AXIS_BINDING_NULL_VALUE; - } - - bool InputControlSystem::detectingBindingState() - { - return mDetectingBindingControl != NULL; - } - - void InputControlSystem::cancelDetectingBindingState() - { - mDetectingBindingControl = NULL; - } - - std::string InputControlSystem::scancodeToString(SDL_Scancode key) - { - SDL_Keycode code = SDL_GetKeyFromScancode(key); - if (code == SDLK_UNKNOWN) - return std::string(SDL_GetScancodeName(key)); - else - return std::string(SDL_GetKeyName(code)); - } - - void InputControlSystem::adjustMouseRegion(Uint16 width, Uint16 height) - { - mClientWidth = width; - mClientHeight = height; - } -} +/* ------------------------------------------------------- +Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the +Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions of +the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------- */ + +#include "ICSInputControlSystem.h" + +namespace ICS +{ + const float ICS_MAX = std::numeric_limits::max(); + + InputControlSystem::InputControlSystem(std::string file, bool active + , DetectingBindingListener* detectingBindingListener + , InputControlSystemLog* log, size_t channelCount) + : mFileName(file) + , mDeadZone(0.1f) + , mLog(log) + , mDetectingBindingListener(detectingBindingListener) + , mDetectingBindingControl(NULL) + , mDetectingBindingDirection(Control::STOP) + , mXmouseAxisBinded(false), mYmouseAxisBinded(false) + , mClientWidth(1) + , mClientHeight(1) + { + ICS_LOG(" - Creating InputControlSystem - "); + + this->mActive = active; + + ICS_LOG("Channel count = " + ToString(channelCount) ); + for(size_t i=0;iLoadFile(); + + if(xmlDoc->Error()) + { + std::ostringstream message; + message << "TinyXml reported an error reading \""+ file + "\". Row " << + (int)xmlDoc->ErrorRow() << ", Col " << (int)xmlDoc->ErrorCol() << ": " << + xmlDoc->ErrorDesc() ; + ICS_LOG(message.str()); + + delete xmlDoc; + return; + } + + xmlRoot = xmlDoc->RootElement(); + if(std::string(xmlRoot->Value()) != "Controller") { + ICS_LOG("Error: Invalid Controller file. Missing element."); + delete xmlDoc; + return; + } + + TiXmlElement* xmlControl = xmlRoot->FirstChildElement("Control"); + + size_t controlChannelCount = 0; + while(xmlControl) + { + TiXmlElement* xmlChannel = xmlControl->FirstChildElement("Channel"); + while(xmlChannel) + { + controlChannelCount = std::max(channelCount, FromString(xmlChannel->Attribute("number"))+1); + + xmlChannel = xmlChannel->NextSiblingElement("Channel"); + } + + xmlControl = xmlControl->NextSiblingElement("Control"); + } + + static const size_t channelsCountLimit = 65536; + if (controlChannelCount > channelsCountLimit) + { + ICS_LOG("Warning: requested channels count (" + ToString(controlChannelCount) + ") exceeds allowed maximum (" + ToString(channelsCountLimit) + "), clamping it"); + controlChannelCount = channelsCountLimit; + } + + if(controlChannelCount > channelCount) + { + size_t dif = controlChannelCount - channelCount; + ICS_LOG("Warning: default channel count exceeded. Adding " + ToString(dif) + " channels" ); + for(size_t i = channelCount ; i < controlChannelCount ; i++) + { + mChannels.push_back(new Channel((int)i)); + } + } + + ICS_LOG("Applying filters to channels"); + // + // + // + // + + TiXmlElement* xmlChannelFilter = xmlRoot->FirstChildElement("ChannelFilter"); + while(xmlChannelFilter) + { + size_t ch = FromString(xmlChannelFilter->Attribute("number")); + if(ch >= controlChannelCount) + { + ICS_LOG("ERROR: channel number (ch) is out of range"); + xmlChannelFilter = xmlChannelFilter->NextSiblingElement("ChannelFilter"); + continue; + } + + TiXmlElement* xmlInterval = xmlChannelFilter->FirstChildElement("Interval"); + while(xmlInterval) + { + std::string type = xmlInterval->Attribute("type"); + + if(type == "bezier") + { + float startX = FromString(xmlInterval->Attribute("startX")); + float startY = FromString(xmlInterval->Attribute("startY")); + float midX = FromString(xmlInterval->Attribute("midX")); + float midY = FromString(xmlInterval->Attribute("midY")); + float endX = FromString(xmlInterval->Attribute("endX")); + float endY = FromString(xmlInterval->Attribute("endY")); + + float step = FromString(xmlInterval->Attribute("step")); + + ICS_LOG("Applying Bezier filter to channel [number=" + + ToString(ch) + ", startX=" + + ToString(startX) + ", startY=" + + ToString(startY) + ", midX=" + + ToString(midX) + ", midY=" + + ToString(midY) + ", endX=" + + ToString(endX) + ", endY=" + + ToString(endY) + ", step=" + + ToString(step) + "]"); + + mChannels.at(ch)->addBezierInterval(startX, startY, midX, midY, endX, endY, step); + } + + xmlInterval = xmlInterval->NextSiblingElement("Interval"); + } + + xmlChannelFilter = xmlChannelFilter->NextSiblingElement("ChannelFilter"); + } + + xmlControl = xmlRoot->FirstChildElement("Control"); + while(xmlControl) + { + bool axisBindable = true; + if(xmlControl->Attribute("axisBindable")) + { + axisBindable = (std::string( xmlControl->Attribute("axisBindable") ) == "true"); + } + + ICS_LOG("Adding Control [name=" + + std::string( xmlControl->Attribute("name") ) + ", autoChangeDirectionOnLimitsAfterStop=" + + std::string( xmlControl->Attribute("autoChangeDirectionOnLimitsAfterStop") ) + ", autoReverseToInitialValue=" + + std::string( xmlControl->Attribute("autoReverseToInitialValue") ) + ", initialValue=" + + std::string( xmlControl->Attribute("initialValue") ) + ", stepSize=" + + std::string( xmlControl->Attribute("stepSize") ) + ", stepsPerSeconds=" + + std::string( xmlControl->Attribute("stepsPerSeconds") ) + ", axisBindable=" + + std::string( (axisBindable)? "true" : "false" ) + "]"); + + float _stepSize = 0; + if(xmlControl->Attribute("stepSize")) + { + std::string value(xmlControl->Attribute("stepSize")); + if(value == "MAX") + { + _stepSize = ICS_MAX; + } + else + { + _stepSize = FromString(value.c_str()); + } + } + else + { + ICS_LOG("Warning: no stepSize value found. Default value is 0."); + } + + float _stepsPerSeconds = 0; + if(xmlControl->Attribute("stepsPerSeconds")) + { + std::string value(xmlControl->Attribute("stepsPerSeconds")); + if(value == "MAX") + { + _stepsPerSeconds = ICS_MAX; + } + else + { + _stepsPerSeconds = FromString(value.c_str()); + } + } + else + { + ICS_LOG("Warning: no stepSize value found. Default value is 0."); + } + + addControl( new Control(xmlControl->Attribute("name") + , std::string( xmlControl->Attribute("autoChangeDirectionOnLimitsAfterStop") ) == "true" + , std::string( xmlControl->Attribute("autoReverseToInitialValue") ) == "true" + , FromString(xmlControl->Attribute("initialValue")) + , _stepSize + , _stepsPerSeconds + , axisBindable) ); + + loadKeyBinders(xmlControl); + + loadMouseAxisBinders(xmlControl); + + loadMouseButtonBinders(xmlControl); + + loadJoystickAxisBinders(xmlControl); + + loadJoystickButtonBinders(xmlControl); + + /* ---------------------------------------------------------------------------------------- + * OPENMW CODE STARTS HERE + * Mouse Wheel support added by Michael Stopa (Stomy) */ + + loadMouseWheelBinders(xmlControl); + + /* OPENMW CODE ENDS HERE + * ------------------------------------------------------------------------------------- */ + + // Attach controls to channels + TiXmlElement* xmlChannel = xmlControl->FirstChildElement("Channel"); + while(xmlChannel) + { + ICS_LOG("\tAttaching control to channel [number=" + + std::string( xmlChannel->Attribute("number") ) + ", direction=" + + std::string( xmlChannel->Attribute("direction") ) + "]"); + + float percentage = 1; + if(xmlChannel->Attribute("percentage")) + { + if(StringIsNumber(xmlChannel->Attribute("percentage"))) + { + float val = FromString(xmlChannel->Attribute("percentage")); + if(val > 1 || val < 0) + { + ICS_LOG("ERROR: attaching percentage value range is [0,1]"); + } + else + { + percentage = val; + } + } + else + { + ICS_LOG("ERROR: attaching percentage value range is [0,1]"); + } + } + + size_t chNumber = FromString(xmlChannel->Attribute("number")); + if(chNumber >= controlChannelCount) + { + ICS_LOG("ERROR: channel number (chNumber) is out of range"); + } + else + { + if(std::string(xmlChannel->Attribute("direction")) == "DIRECT") + { + mControls.back()->attachChannel(mChannels[ chNumber ],Channel::DIRECT, percentage); + } + else if(std::string(xmlChannel->Attribute("direction")) == "INVERSE") + { + mControls.back()->attachChannel(mChannels[ chNumber ],Channel::INVERSE, percentage); + } + } + + xmlChannel = xmlChannel->NextSiblingElement("Channel"); + } + + xmlControl = xmlControl->NextSiblingElement("Control"); + } + + std::vector::const_iterator o; + for(o = mChannels.begin(); o != mChannels.end(); ++o) + { + (*o)->update(); + } + + delete xmlDoc; + } + + ICS_LOG(" - InputControlSystem Created - "); + } + + InputControlSystem::~InputControlSystem() + { + ICS_LOG(" - Deleting InputControlSystem (" + mFileName + ") - "); + + mJoystickIDList.clear(); + + std::vector::const_iterator o; + for(o = mChannels.begin(); o != mChannels.end(); ++o) + { + delete (*o); + } + mChannels.clear(); + + std::vector::const_iterator o2; + for(o2 = mControls.begin(); o2 != mControls.end(); ++o2) + { + delete (*o2); + } + mControls.clear(); + + mControlsKeyBinderMap.clear(); + mControlsMouseButtonBinderMap.clear(); + mControlsJoystickButtonBinderMap.clear(); + + /* ---------------------------------------------------------------------------------------- + * OPENMW CODE STARTS HERE + * Mouse Wheel support added by Michael Stopa (Stomy) */ + + mControlsMouseWheelBinderMap.clear(); + + /* OPENMW CODE ENDS HERE + * ------------------------------------------------------------------------------------- */ + + ICS_LOG(" - InputControlSystem deleted - "); + } + + std::string InputControlSystem::getBaseFileName() + { + size_t found = mFileName.find_last_of("/\\"); + std::string file = mFileName.substr(found+1); + + return file.substr(0, file.find_last_of(".")); + } + + bool InputControlSystem::save(std::string fileName) + { + if(fileName != "") + { + mFileName = fileName; + } + + TiXmlDocument doc( mFileName.c_str() ); + + TiXmlDeclaration dec; + dec.Parse( "", 0, TIXML_ENCODING_UNKNOWN ); + doc.InsertEndChild(dec); + + TiXmlElement Controller( "Controller" ); + + for(std::vector::const_iterator o = mChannels.begin() ; o != mChannels.end(); ++o) + { + ICS::IntervalList intervals = (*o)->getIntervals(); + + if(intervals.size() > 1) // all channels have a default linear filter + { + TiXmlElement ChannelFilter( "ChannelFilter" ); + + ChannelFilter.SetAttribute("number", ToString((*o)->getNumber()).c_str()); + + ICS::IntervalList::const_iterator interval = intervals.begin(); + while( interval != intervals.end() ) + { + // if not default linear filter + if(!( interval->step == 0.2f + && interval->startX == 0.0f + && interval->startY == 0.0f + && interval->midX == 0.5f + && interval->midY == 0.5f + && interval->endX == 1.0f + && interval->endY == 1.0f )) + { + TiXmlElement XMLInterval( "Interval" ); + + XMLInterval.SetAttribute("type", "bezier"); + XMLInterval.SetAttribute("step", ToString(interval->step).c_str()); + + XMLInterval.SetAttribute("startX", ToString(interval->startX).c_str()); + XMLInterval.SetAttribute("startY", ToString(interval->startY).c_str()); + XMLInterval.SetAttribute("midX", ToString(interval->midX).c_str()); + XMLInterval.SetAttribute("midY", ToString(interval->midY).c_str()); + XMLInterval.SetAttribute("endX", ToString(interval->endX).c_str()); + XMLInterval.SetAttribute("endY", ToString(interval->endY).c_str()); + + ChannelFilter.InsertEndChild(XMLInterval); + } + + ++interval; + } + + Controller.InsertEndChild(ChannelFilter); + } + } + + for(std::vector::const_iterator o = mControls.begin() ; o != mControls.end(); ++o) + { + TiXmlElement control( "Control" ); + + control.SetAttribute( "name", (*o)->getName().c_str() ); + if((*o)->getAutoChangeDirectionOnLimitsAfterStop()) + { + control.SetAttribute( "autoChangeDirectionOnLimitsAfterStop", "true" ); + } + else + { + control.SetAttribute( "autoChangeDirectionOnLimitsAfterStop", "false" ); + } + if((*o)->getAutoReverse()) + { + control.SetAttribute( "autoReverseToInitialValue", "true" ); + } + else + { + control.SetAttribute( "autoReverseToInitialValue", "false" ); + } + control.SetAttribute( "initialValue", ToString((*o)->getInitialValue()).c_str() ); + + if((*o)->getStepSize() == ICS_MAX) + { + control.SetAttribute( "stepSize", "MAX" ); + } + else + { + control.SetAttribute( "stepSize", ToString((*o)->getStepSize()).c_str() ); + } + + if((*o)->getStepsPerSeconds() == ICS_MAX) + { + control.SetAttribute( "stepsPerSeconds", "MAX" ); + } + else + { + control.SetAttribute( "stepsPerSeconds", ToString((*o)->getStepsPerSeconds()).c_str() ); + } + + if(!(*o)->isAxisBindable()) + { + control.SetAttribute( "axisBindable", "false" ); + } + + if(getKeyBinding(*o, Control/*::ControlChangingDirection*/::INCREASE) != SDL_SCANCODE_UNKNOWN) + { + TiXmlElement keyBinder( "KeyBinder" ); + + keyBinder.SetAttribute( "key", ToString( + getKeyBinding(*o, Control/*::ControlChangingDirection*/::INCREASE)).c_str() ); + keyBinder.SetAttribute( "direction", "INCREASE" ); + control.InsertEndChild(keyBinder); + } + + if(getKeyBinding(*o, Control/*::ControlChangingDirection*/::DECREASE) != SDL_SCANCODE_UNKNOWN) + { + TiXmlElement keyBinder( "KeyBinder" ); + + keyBinder.SetAttribute( "key", ToString( + getKeyBinding(*o, Control/*::ControlChangingDirection*/::DECREASE)).c_str() ); + keyBinder.SetAttribute( "direction", "DECREASE" ); + control.InsertEndChild(keyBinder); + } + + if(getMouseAxisBinding(*o, Control/*::ControlChangingDirection*/::INCREASE) + != InputControlSystem/*::NamedAxis*/::UNASSIGNED) + { + TiXmlElement binder( "MouseBinder" ); + + InputControlSystem::NamedAxis axis = + getMouseAxisBinding(*o, Control/*::ControlChangingDirection*/::INCREASE); + if(axis == InputControlSystem/*::NamedAxis*/::X) + { + binder.SetAttribute( "axis", "X" ); + } + else if(axis == InputControlSystem/*::NamedAxis*/::Y) + { + binder.SetAttribute( "axis", "Y" ); + } + else if(axis == InputControlSystem/*::NamedAxis*/::Z) + { + binder.SetAttribute( "axis", "Z" ); + } + + binder.SetAttribute( "direction", "INCREASE" ); + control.InsertEndChild(binder); + } + + if(getMouseAxisBinding(*o, Control/*::ControlChangingDirection*/::DECREASE) + != InputControlSystem/*::NamedAxis*/::UNASSIGNED) + { + TiXmlElement binder( "MouseBinder" ); + + InputControlSystem::NamedAxis axis = + getMouseAxisBinding(*o, Control/*::ControlChangingDirection*/::DECREASE); + if(axis == InputControlSystem/*::NamedAxis*/::X) + { + binder.SetAttribute( "axis", "X" ); + } + else if(axis == InputControlSystem/*::NamedAxis*/::Y) + { + binder.SetAttribute( "axis", "Y" ); + } + else if(axis == InputControlSystem/*::NamedAxis*/::Z) + { + binder.SetAttribute( "axis", "Z" ); + } + + binder.SetAttribute( "direction", "DECREASE" ); + control.InsertEndChild(binder); + } + + /* ---------------------------------------------------------------------------------------- + * OPENMW CODE STARTS HERE + * Mouse Wheel support added by Stomy */ + + if(getMouseWheelBinding(*o, Control::INCREASE) != MouseWheelClick::UNASSIGNED) + { + TiXmlElement binder( "MouseWheelBinder" ); + MouseWheelClick click = getMouseWheelBinding(*o, Control::INCREASE); + bool skip = false; + switch (click) { + case MouseWheelClick::UP: { + binder.SetAttribute("button", "UP"); + } break; + case MouseWheelClick::DOWN: { + binder.SetAttribute("button", "DOWN"); + } break; + case MouseWheelClick::RIGHT: { + binder.SetAttribute("button", "RIGHT"); + } break; + case MouseWheelClick::LEFT: { + binder.SetAttribute("button", "LEFT"); + } break; + default: { + skip = true; + } break; + } + binder.SetAttribute( "direction", "INCREASE" ); + if (!skip) + control.InsertEndChild(binder); + } + + if(getMouseWheelBinding(*o, Control::DECREASE) != MouseWheelClick::UNASSIGNED) + { + TiXmlElement binder( "MouseWheelBinder" ); + MouseWheelClick click = getMouseWheelBinding(*o, Control::INCREASE); + bool skip = false; + switch (click) { + case MouseWheelClick::UP: { + binder.SetAttribute("button", "UP"); + } break; + case MouseWheelClick::DOWN: { + binder.SetAttribute("button", "DOWN"); + } break; + case MouseWheelClick::RIGHT: { + binder.SetAttribute("button", "RIGHT"); + } break; + case MouseWheelClick::LEFT: { + binder.SetAttribute("button", "LEFT"); + } break; + default: { + skip = true; + } break; + } + binder.SetAttribute( "direction", "DECREASE" ); + if (!skip) + control.InsertEndChild(binder); + } + + /* OPENMW CODE ENDS HERE + * ------------------------------------------------------------------------------------- */ + + if(getMouseButtonBinding(*o, Control/*::ControlChangingDirection*/::INCREASE) + != ICS_MAX_DEVICE_BUTTONS) + { + TiXmlElement binder( "MouseButtonBinder" ); + + unsigned int button = getMouseButtonBinding(*o, Control/*::ControlChangingDirection*/::INCREASE); + if(button == SDL_BUTTON_LEFT) + { + binder.SetAttribute( "button", "LEFT" ); + } + else if(button == SDL_BUTTON_MIDDLE) + { + binder.SetAttribute( "button", "MIDDLE" ); + } + else if(button == SDL_BUTTON_RIGHT) + { + binder.SetAttribute( "button", "RIGHT" ); + } + else + { + binder.SetAttribute( "button", ToString(button).c_str() ); + } + binder.SetAttribute( "direction", "INCREASE" ); + control.InsertEndChild(binder); + } + + if(getMouseButtonBinding(*o, Control/*::ControlChangingDirection*/::DECREASE) + != ICS_MAX_DEVICE_BUTTONS) + { + TiXmlElement binder( "MouseButtonBinder" ); + + unsigned int button = getMouseButtonBinding(*o, Control/*::ControlChangingDirection*/::DECREASE); + if(button == SDL_BUTTON_LEFT) + { + binder.SetAttribute( "button", "LEFT" ); + } + else if(button == SDL_BUTTON_MIDDLE) + { + binder.SetAttribute( "button", "MIDDLE" ); + } + else if(button == SDL_BUTTON_RIGHT) + { + binder.SetAttribute( "button", "RIGHT" ); + } + else + { + binder.SetAttribute( "button", ToString(button).c_str() ); + } + binder.SetAttribute( "direction", "DECREASE" ); + control.InsertEndChild(binder); + } + JoystickIDList::const_iterator it = mJoystickIDList.begin(); + while(it!=mJoystickIDList.end()) + { + int deviceID = *it; + if(getJoystickAxisBinding(*o, deviceID, Control/*::ControlChangingDirection*/::INCREASE) + != /*NamedAxis::*/UNASSIGNED) + { + TiXmlElement binder( "JoystickAxisBinder" ); + + binder.SetAttribute( "axis", ToString( + getJoystickAxisBinding(*o, deviceID, Control/*::ControlChangingDirection*/::INCREASE)).c_str() ); + + binder.SetAttribute( "direction", "INCREASE" ); + + binder.SetAttribute( "deviceId", deviceID ); //completely useless, but required for backwards compatability + + control.InsertEndChild(binder); + } + + if(getJoystickAxisBinding(*o, deviceID, Control/*::ControlChangingDirection*/::DECREASE) + != /*NamedAxis::*/UNASSIGNED) + { + TiXmlElement binder( "JoystickAxisBinder" ); + + binder.SetAttribute( "axis", ToString( + getJoystickAxisBinding(*o, deviceID, Control/*::ControlChangingDirection*/::DECREASE)).c_str() ); + + binder.SetAttribute( "direction", "DECREASE" ); + + binder.SetAttribute( "deviceId", deviceID ); //completely useless, but required for backwards compatability + + control.InsertEndChild(binder); + } + + if(getJoystickButtonBinding(*o, deviceID, Control/*::ControlChangingDirection*/::INCREASE) + != ICS_MAX_DEVICE_BUTTONS) + { + TiXmlElement binder( "JoystickButtonBinder" ); + + binder.SetAttribute( "button", ToString( + getJoystickButtonBinding(*o, deviceID, Control/*::ControlChangingDirection*/::INCREASE)).c_str() ); + + binder.SetAttribute( "direction", "INCREASE" ); + + binder.SetAttribute( "deviceId", deviceID ); //completely useless, but required for backwards compatability + + control.InsertEndChild(binder); + } + + if(getJoystickButtonBinding(*o, deviceID, Control/*::ControlChangingDirection*/::DECREASE) + != ICS_MAX_DEVICE_BUTTONS) + { + TiXmlElement binder( "JoystickButtonBinder" ); + + binder.SetAttribute( "button", ToString( + getJoystickButtonBinding(*o, deviceID, Control/*::ControlChangingDirection*/::DECREASE)).c_str() ); + + binder.SetAttribute( "direction", "DECREASE" ); + + binder.SetAttribute( "deviceId", deviceID ); //completely useless, but required for backwards compatability + + control.InsertEndChild(binder); + } + it++; + } + + + std::list channels = (*o)->getAttachedChannels(); + for(std::list::iterator it = channels.begin() ; + it != channels.end() ; ++it) + { + TiXmlElement binder( "Channel" ); + + binder.SetAttribute( "number", ToString((*it)->getNumber()).c_str() ); + + Channel::ChannelDirection direction = (*it)->getAttachedControlBinding(*o).direction; + if(direction == Channel/*::ChannelDirection*/::DIRECT) + { + binder.SetAttribute( "direction", "DIRECT" ); + } + else + { + binder.SetAttribute( "direction", "INVERSE" ); + } + + float percentage = (*it)->getAttachedControlBinding(*o).percentage; + binder.SetAttribute( "percentage", ToString(percentage).c_str() ); + + control.InsertEndChild(binder); + } + + Controller.InsertEndChild(control); + } + + doc.InsertEndChild(Controller); + return doc.SaveFile(); + } + + void InputControlSystem::update(float lTimeSinceLastFrame) + { + if(mActive) + { + std::vector::const_iterator it; + for(it=mControls.begin(); it!=mControls.end(); ++it) + { + (*it)->update(lTimeSinceLastFrame); + } + } + + //! @todo Future versions should consider channel exponentials and mixtures, so + // after updating Controls, Channels should be updated according to their values + } + + float InputControlSystem::getChannelValue(int i) + { + return std::max(0.0,std::min(1.0,mChannels[i]->getValue())); + } + + float InputControlSystem::getControlValue(int i) + { + return mControls[i]->getValue(); + } + + Control* InputControlSystem::findControl(std::string name) + { + if(mActive) + { + std::vector::const_iterator it; + for(it = mControls.begin(); it != mControls.end(); ++it) + { + if( ((Control*)(*it))->getName() == name) + { + return (Control*)(*it); + } + } + } + + return NULL; + } + + void InputControlSystem::enableDetectingBindingState(Control* control + , Control::ControlChangingDirection direction) + { + mDetectingBindingControl = control; + mDetectingBindingDirection = direction; + + mMouseAxisBindingInitialValues[0] = ICS_MOUSE_AXIS_BINDING_NULL_VALUE; + } + + bool InputControlSystem::detectingBindingState() + { + return mDetectingBindingControl != NULL; + } + + void InputControlSystem::cancelDetectingBindingState() + { + mDetectingBindingControl = NULL; + } + + std::string InputControlSystem::scancodeToString(SDL_Scancode key) + { + SDL_Keycode code = SDL_GetKeyFromScancode(key); + if (code == SDLK_UNKNOWN) + return std::string(SDL_GetScancodeName(key)); + else + return std::string(SDL_GetKeyName(code)); + } + + void InputControlSystem::adjustMouseRegion(Uint16 width, Uint16 height) + { + mClientWidth = width; + mClientHeight = height; + } +} diff --git a/extern/oics/ICSInputControlSystem.h b/extern/oics/ICSInputControlSystem.h index c49224dc2b..97ab8d2edf 100644 --- a/extern/oics/ICSInputControlSystem.h +++ b/extern/oics/ICSInputControlSystem.h @@ -1,281 +1,281 @@ -/* ------------------------------------------------------- -Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the -Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions of -the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS -OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------- */ - -#ifndef OICS_InputControlSystem_H_ -#define OICS_InputControlSystem_H_ - -#include "ICSPrerequisites.h" - -#include "ICSControl.h" -#include "ICSChannel.h" - -#define ICS_LOG(text) if(mLog) mLog->logMessage( ("ICS: " + std::string(text)).c_str() ); -#define ICS_MAX_JOYSTICK_AXIS 16 -#define ICS_MOUSE_BINDING_MARGIN 30 -#define ICS_JOYSTICK_AXIS_BINDING_MARGIN 10000 -#define ICS_JOYSTICK_SLIDER_BINDING_MARGIN 10000 -#define ICS_MOUSE_AXIS_BINDING_NULL_VALUE std::numeric_limits::max() - -namespace ICS -{ - class DllExport InputControlSystemLog - { - public: - virtual void logMessage(const char* text) = 0; - - virtual ~InputControlSystemLog() = default; - }; - - class DllExport InputControlSystem - { - - public: - - enum NamedAxis { X = -1, Y = -2, Z = -3, UNASSIGNED = -4 }; - enum POVAxis { NorthSouth = 0, EastWest = 1 }; - - typedef NamedAxis MouseAxis; // MouseAxis is deprecated. It will be removed in future versions - - typedef std::map JoystickInstanceMap; - typedef std::list JoystickIDList; - - typedef struct - { - int index; - POVAxis axis; - } POVBindingPair; - - InputControlSystem(std::string file = "", bool active = true - , DetectingBindingListener* detectingBindingListener = NULL - , InputControlSystemLog* log = NULL, size_t channelCount = 16); - ~InputControlSystem(); - - std::string getFileName(){ return mFileName; }; - std::string getBaseFileName(); - - void setDetectingBindingListener(DetectingBindingListener* detectingBindingListener){ mDetectingBindingListener = detectingBindingListener; }; - DetectingBindingListener* getDetectingBindingListener(){ return mDetectingBindingListener; }; - - void setJoystickDeadZone(float deadZone){ mDeadZone = deadZone; }; - - // in seconds - void update(float timeSinceLastFrame); - - inline Channel* getChannel(int i){ return mChannels[i]; }; - float getChannelValue(int i); - inline int getChannelCount(){ return (int)mChannels.size(); }; - - inline Control* getControl(int i){ return mControls[i]; }; - float getControlValue(int i); - inline int getControlCount(){ return (int)mControls.size(); }; - inline void addControl(Control* control){ mControls.push_back(control); }; - - Control* findControl(std::string name); - - inline void activate(){ this->mActive = true; }; - inline void deactivate(){ this->mActive = false; }; - - void controllerAdded (int deviceID, const SDL_ControllerDeviceEvent &args); - void controllerRemoved(const SDL_ControllerDeviceEvent &args); - JoystickIDList& getJoystickIdList(){ return mJoystickIDList; }; - JoystickInstanceMap& getJoystickInstanceMap(){ return mJoystickInstanceMap; }; - - // MouseListener - void mouseMoved(const SDL_MouseMotionEvent &evt); - void mousePressed(const SDL_MouseButtonEvent &evt, Uint8); - void mouseReleased(const SDL_MouseButtonEvent &evt, Uint8); - - // KeyListener - void keyPressed(const SDL_KeyboardEvent &evt); - void keyReleased(const SDL_KeyboardEvent &evt); - - // ControllerListener - void buttonPressed(int deviceID, const SDL_ControllerButtonEvent &evt); - void buttonReleased(int deviceID, const SDL_ControllerButtonEvent &evt); - void axisMoved(int deviceID, const SDL_ControllerAxisEvent &evt); - - void addKeyBinding(Control* control, SDL_Scancode key, Control::ControlChangingDirection direction); - bool isKeyBound(SDL_Scancode key) const; - void addMouseAxisBinding(Control* control, NamedAxis axis, Control::ControlChangingDirection direction); - void addMouseButtonBinding(Control* control, unsigned int button, Control::ControlChangingDirection direction); - bool isMouseButtonBound(unsigned int button) const; - void addJoystickAxisBinding(Control* control, int deviceID, int axis, Control::ControlChangingDirection direction); - void addJoystickButtonBinding(Control* control, int deviceID, unsigned int button, Control::ControlChangingDirection direction); - bool isJoystickButtonBound(int deviceID, unsigned int button) const; - bool isJoystickAxisBound(int deviceID, unsigned int axis) const; - void removeKeyBinding(SDL_Scancode key); - void removeMouseAxisBinding(NamedAxis axis); - void removeMouseButtonBinding(unsigned int button); - void removeJoystickAxisBinding(int deviceID, int axis); - void removeJoystickButtonBinding(int deviceID, unsigned int button); - - SDL_Scancode getKeyBinding(Control* control, ICS::Control::ControlChangingDirection direction); - NamedAxis getMouseAxisBinding(Control* control, ICS::Control::ControlChangingDirection direction); - unsigned int getMouseButtonBinding(Control* control, ICS::Control::ControlChangingDirection direction); - int getJoystickAxisBinding(Control* control, int deviceID, ICS::Control::ControlChangingDirection direction); - unsigned int getJoystickButtonBinding(Control* control, int deviceID, ICS::Control::ControlChangingDirection direction); - - std::string scancodeToString(SDL_Scancode key); - - void enableDetectingBindingState(Control* control, Control::ControlChangingDirection direction); - void cancelDetectingBindingState(); - bool detectingBindingState(); - - bool save(std::string fileName = ""); - - void adjustMouseRegion (Uint16 width, Uint16 height); - - protected: - - void loadKeyBinders(TiXmlElement* xmlControlNode); - void loadMouseAxisBinders(TiXmlElement* xmlControlNode); - void loadMouseButtonBinders(TiXmlElement* xmlControlNode); - void loadJoystickAxisBinders(TiXmlElement* xmlControlNode); - void loadJoystickButtonBinders(TiXmlElement* xmlControlNode); - void loadJoystickPOVBinders(TiXmlElement* xmlControlNode); - void loadJoystickSliderBinders(TiXmlElement* xmlControlNode); - - void addMouseAxisBinding_(Control* control, int axis, Control::ControlChangingDirection direction); - void removeMouseAxisBinding_(int axis); - - protected: - - typedef struct { - Control::ControlChangingDirection direction; - Control* control; - } ControlKeyBinderItem; - - typedef ControlKeyBinderItem ControlAxisBinderItem; - typedef ControlKeyBinderItem ControlButtonBinderItem; - typedef ControlKeyBinderItem ControlPOVBinderItem; - typedef ControlKeyBinderItem ControlSliderBinderItem; - - typedef struct { - Control* control; - Control::ControlChangingDirection direction; - } PendingActionItem; - - std::list mPendingActions; - - std::string mFileName; - - float mDeadZone; - - typedef std::map ControlsKeyBinderMapType; // - typedef std::map ControlsAxisBinderMapType; // - typedef std::map ControlsButtonBinderMapType; // - - typedef std::map JoystickAxisBinderMapType; // > - typedef std::map JoystickButtonBinderMapType; // > - - ControlsAxisBinderMapType mControlsMouseAxisBinderMap; // - ControlsButtonBinderMapType mControlsMouseButtonBinderMap; // - JoystickAxisBinderMapType mControlsJoystickAxisBinderMap; // - JoystickButtonBinderMapType mControlsJoystickButtonBinderMap; // - - std::vector mControls; - std::vector mChannels; - - ControlsKeyBinderMapType mControlsKeyBinderMap; - - bool mActive; - InputControlSystemLog* mLog; - - DetectingBindingListener* mDetectingBindingListener; - Control* mDetectingBindingControl; - Control::ControlChangingDirection mDetectingBindingDirection; - - bool mXmouseAxisBinded; - bool mYmouseAxisBinded; - - JoystickIDList mJoystickIDList; - JoystickInstanceMap mJoystickInstanceMap; - - int mMouseAxisBindingInitialValues[3]; - - private: - - Uint16 mClientWidth; - Uint16 mClientHeight; - - /* ---------------------------------------------------------------------------------------- - * OPENMW CODE STARTS HERE - * Mouse Wheel support added by Michael Stopa (Stomy) */ - - public: - enum class MouseWheelClick : int { UNASSIGNED = 0, UP = 1, DOWN = 2, LEFT = 3, RIGHT = 4}; - - void mouseWheelMoved(const SDL_MouseWheelEvent &evt); - void addMouseWheelBinding(Control* control, MouseWheelClick click, Control::ControlChangingDirection direction); - void removeMouseWheelBinding(MouseWheelClick click); - MouseWheelClick getMouseWheelBinding(Control* control, ICS::Control::ControlChangingDirection direction); - bool isMouseWheelBound(MouseWheelClick button) const; - - protected: - void loadMouseWheelBinders(TiXmlElement* xmlControlNode); - ControlsButtonBinderMapType mControlsMouseWheelBinderMap; - - /* OPENMW CODE ENDS HERE - * ------------------------------------------------------------------------------------- */ - }; - - class DllExport DetectingBindingListener - { - public: - virtual void keyBindingDetected(InputControlSystem* ICS, Control* control - , SDL_Scancode key, Control::ControlChangingDirection direction); - - virtual void mouseAxisBindingDetected(InputControlSystem* ICS, Control* control - , InputControlSystem::NamedAxis axis, Control::ControlChangingDirection direction); - - virtual void mouseButtonBindingDetected(InputControlSystem* ICS, Control* control - , unsigned int button, Control::ControlChangingDirection direction); - - virtual void joystickAxisBindingDetected(InputControlSystem* ICS, int deviceID, Control* control - , int axis, Control::ControlChangingDirection direction); - - virtual void joystickButtonBindingDetected(InputControlSystem* ICS, int deviceID, Control* control - , unsigned int button, Control::ControlChangingDirection direction); - - /* ---------------------------------------------------------------------------------------- - * OPENMW CODE STARTS HERE - * Mouse Wheel support added by Michael Stopa (Stomy) */ - - virtual void mouseWheelBindingDetected(InputControlSystem* ICS, Control* control, - InputControlSystem::MouseWheelClick click, - Control::ControlChangingDirection direction); - - virtual ~DetectingBindingListener() = default; - - /* OPENMW CODE ENDS HERE - * ------------------------------------------------------------------------------------- */ - }; - - extern const float ICS_MAX; -} - - -#endif +/* ------------------------------------------------------- +Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the +Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions of +the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------- */ + +#ifndef OICS_InputControlSystem_H_ +#define OICS_InputControlSystem_H_ + +#include "ICSPrerequisites.h" + +#include "ICSControl.h" +#include "ICSChannel.h" + +#define ICS_LOG(text) if(mLog) mLog->logMessage( ("ICS: " + std::string(text)).c_str() ); +#define ICS_MAX_JOYSTICK_AXIS 16 +#define ICS_MOUSE_BINDING_MARGIN 30 +#define ICS_JOYSTICK_AXIS_BINDING_MARGIN 10000 +#define ICS_JOYSTICK_SLIDER_BINDING_MARGIN 10000 +#define ICS_MOUSE_AXIS_BINDING_NULL_VALUE std::numeric_limits::max() + +namespace ICS +{ + class DllExport InputControlSystemLog + { + public: + virtual void logMessage(const char* text) = 0; + + virtual ~InputControlSystemLog() = default; + }; + + class DllExport InputControlSystem + { + + public: + + enum NamedAxis { X = -1, Y = -2, Z = -3, UNASSIGNED = -4 }; + enum POVAxis { NorthSouth = 0, EastWest = 1 }; + + typedef NamedAxis MouseAxis; // MouseAxis is deprecated. It will be removed in future versions + + typedef std::map JoystickInstanceMap; + typedef std::list JoystickIDList; + + typedef struct + { + int index; + POVAxis axis; + } POVBindingPair; + + InputControlSystem(std::string file = "", bool active = true + , DetectingBindingListener* detectingBindingListener = NULL + , InputControlSystemLog* log = NULL, size_t channelCount = 16); + ~InputControlSystem(); + + std::string getFileName(){ return mFileName; }; + std::string getBaseFileName(); + + void setDetectingBindingListener(DetectingBindingListener* detectingBindingListener){ mDetectingBindingListener = detectingBindingListener; }; + DetectingBindingListener* getDetectingBindingListener(){ return mDetectingBindingListener; }; + + void setJoystickDeadZone(float deadZone){ mDeadZone = deadZone; }; + + // in seconds + void update(float timeSinceLastFrame); + + inline Channel* getChannel(int i){ return mChannels[i]; }; + float getChannelValue(int i); + inline int getChannelCount(){ return (int)mChannels.size(); }; + + inline Control* getControl(int i){ return mControls[i]; }; + float getControlValue(int i); + inline int getControlCount(){ return (int)mControls.size(); }; + inline void addControl(Control* control){ mControls.push_back(control); }; + + Control* findControl(std::string name); + + inline void activate(){ this->mActive = true; }; + inline void deactivate(){ this->mActive = false; }; + + void controllerAdded (int deviceID, const SDL_ControllerDeviceEvent &args); + void controllerRemoved(const SDL_ControllerDeviceEvent &args); + JoystickIDList& getJoystickIdList(){ return mJoystickIDList; }; + JoystickInstanceMap& getJoystickInstanceMap(){ return mJoystickInstanceMap; }; + + // MouseListener + void mouseMoved(const SDL_MouseMotionEvent &evt); + void mousePressed(const SDL_MouseButtonEvent &evt, Uint8); + void mouseReleased(const SDL_MouseButtonEvent &evt, Uint8); + + // KeyListener + void keyPressed(const SDL_KeyboardEvent &evt); + void keyReleased(const SDL_KeyboardEvent &evt); + + // ControllerListener + void buttonPressed(int deviceID, const SDL_ControllerButtonEvent &evt); + void buttonReleased(int deviceID, const SDL_ControllerButtonEvent &evt); + void axisMoved(int deviceID, const SDL_ControllerAxisEvent &evt); + + void addKeyBinding(Control* control, SDL_Scancode key, Control::ControlChangingDirection direction); + bool isKeyBound(SDL_Scancode key) const; + void addMouseAxisBinding(Control* control, NamedAxis axis, Control::ControlChangingDirection direction); + void addMouseButtonBinding(Control* control, unsigned int button, Control::ControlChangingDirection direction); + bool isMouseButtonBound(unsigned int button) const; + void addJoystickAxisBinding(Control* control, int deviceID, int axis, Control::ControlChangingDirection direction); + void addJoystickButtonBinding(Control* control, int deviceID, unsigned int button, Control::ControlChangingDirection direction); + bool isJoystickButtonBound(int deviceID, unsigned int button) const; + bool isJoystickAxisBound(int deviceID, unsigned int axis) const; + void removeKeyBinding(SDL_Scancode key); + void removeMouseAxisBinding(NamedAxis axis); + void removeMouseButtonBinding(unsigned int button); + void removeJoystickAxisBinding(int deviceID, int axis); + void removeJoystickButtonBinding(int deviceID, unsigned int button); + + SDL_Scancode getKeyBinding(Control* control, ICS::Control::ControlChangingDirection direction); + NamedAxis getMouseAxisBinding(Control* control, ICS::Control::ControlChangingDirection direction); + unsigned int getMouseButtonBinding(Control* control, ICS::Control::ControlChangingDirection direction); + int getJoystickAxisBinding(Control* control, int deviceID, ICS::Control::ControlChangingDirection direction); + unsigned int getJoystickButtonBinding(Control* control, int deviceID, ICS::Control::ControlChangingDirection direction); + + std::string scancodeToString(SDL_Scancode key); + + void enableDetectingBindingState(Control* control, Control::ControlChangingDirection direction); + void cancelDetectingBindingState(); + bool detectingBindingState(); + + bool save(std::string fileName = ""); + + void adjustMouseRegion (Uint16 width, Uint16 height); + + protected: + + void loadKeyBinders(TiXmlElement* xmlControlNode); + void loadMouseAxisBinders(TiXmlElement* xmlControlNode); + void loadMouseButtonBinders(TiXmlElement* xmlControlNode); + void loadJoystickAxisBinders(TiXmlElement* xmlControlNode); + void loadJoystickButtonBinders(TiXmlElement* xmlControlNode); + void loadJoystickPOVBinders(TiXmlElement* xmlControlNode); + void loadJoystickSliderBinders(TiXmlElement* xmlControlNode); + + void addMouseAxisBinding_(Control* control, int axis, Control::ControlChangingDirection direction); + void removeMouseAxisBinding_(int axis); + + protected: + + typedef struct { + Control::ControlChangingDirection direction; + Control* control; + } ControlKeyBinderItem; + + typedef ControlKeyBinderItem ControlAxisBinderItem; + typedef ControlKeyBinderItem ControlButtonBinderItem; + typedef ControlKeyBinderItem ControlPOVBinderItem; + typedef ControlKeyBinderItem ControlSliderBinderItem; + + typedef struct { + Control* control; + Control::ControlChangingDirection direction; + } PendingActionItem; + + std::list mPendingActions; + + std::string mFileName; + + float mDeadZone; + + typedef std::map ControlsKeyBinderMapType; // + typedef std::map ControlsAxisBinderMapType; // + typedef std::map ControlsButtonBinderMapType; // + + typedef std::map JoystickAxisBinderMapType; // > + typedef std::map JoystickButtonBinderMapType; // > + + ControlsAxisBinderMapType mControlsMouseAxisBinderMap; // + ControlsButtonBinderMapType mControlsMouseButtonBinderMap; // + JoystickAxisBinderMapType mControlsJoystickAxisBinderMap; // + JoystickButtonBinderMapType mControlsJoystickButtonBinderMap; // + + std::vector mControls; + std::vector mChannels; + + ControlsKeyBinderMapType mControlsKeyBinderMap; + + bool mActive; + InputControlSystemLog* mLog; + + DetectingBindingListener* mDetectingBindingListener; + Control* mDetectingBindingControl; + Control::ControlChangingDirection mDetectingBindingDirection; + + bool mXmouseAxisBinded; + bool mYmouseAxisBinded; + + JoystickIDList mJoystickIDList; + JoystickInstanceMap mJoystickInstanceMap; + + int mMouseAxisBindingInitialValues[3]; + + private: + + Uint16 mClientWidth; + Uint16 mClientHeight; + + /* ---------------------------------------------------------------------------------------- + * OPENMW CODE STARTS HERE + * Mouse Wheel support added by Michael Stopa (Stomy) */ + + public: + enum class MouseWheelClick : int { UNASSIGNED = 0, UP = 1, DOWN = 2, LEFT = 3, RIGHT = 4}; + + void mouseWheelMoved(const SDL_MouseWheelEvent &evt); + void addMouseWheelBinding(Control* control, MouseWheelClick click, Control::ControlChangingDirection direction); + void removeMouseWheelBinding(MouseWheelClick click); + MouseWheelClick getMouseWheelBinding(Control* control, ICS::Control::ControlChangingDirection direction); + bool isMouseWheelBound(MouseWheelClick button) const; + + protected: + void loadMouseWheelBinders(TiXmlElement* xmlControlNode); + ControlsButtonBinderMapType mControlsMouseWheelBinderMap; + + /* OPENMW CODE ENDS HERE + * ------------------------------------------------------------------------------------- */ + }; + + class DllExport DetectingBindingListener + { + public: + virtual void keyBindingDetected(InputControlSystem* ICS, Control* control + , SDL_Scancode key, Control::ControlChangingDirection direction); + + virtual void mouseAxisBindingDetected(InputControlSystem* ICS, Control* control + , InputControlSystem::NamedAxis axis, Control::ControlChangingDirection direction); + + virtual void mouseButtonBindingDetected(InputControlSystem* ICS, Control* control + , unsigned int button, Control::ControlChangingDirection direction); + + virtual void joystickAxisBindingDetected(InputControlSystem* ICS, int deviceID, Control* control + , int axis, Control::ControlChangingDirection direction); + + virtual void joystickButtonBindingDetected(InputControlSystem* ICS, int deviceID, Control* control + , unsigned int button, Control::ControlChangingDirection direction); + + /* ---------------------------------------------------------------------------------------- + * OPENMW CODE STARTS HERE + * Mouse Wheel support added by Michael Stopa (Stomy) */ + + virtual void mouseWheelBindingDetected(InputControlSystem* ICS, Control* control, + InputControlSystem::MouseWheelClick click, + Control::ControlChangingDirection direction); + + virtual ~DetectingBindingListener() = default; + + /* OPENMW CODE ENDS HERE + * ------------------------------------------------------------------------------------- */ + }; + + extern const float ICS_MAX; +} + + +#endif diff --git a/extern/oics/ICSInputControlSystem_joystick.cpp b/extern/oics/ICSInputControlSystem_joystick.cpp index 697d0ed3d3..403e7a2076 100644 --- a/extern/oics/ICSInputControlSystem_joystick.cpp +++ b/extern/oics/ICSInputControlSystem_joystick.cpp @@ -1,266 +1,266 @@ -/* ------------------------------------------------------- -Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the -Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions of -the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS -OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------- */ - -#include "ICSInputControlSystem.h" - -#define SDL_JOY_AXIS_MIN -32768 -#define SDL_JOY_AXIS_MAX 32767 - -namespace ICS -{ - // load xml - void InputControlSystem::loadJoystickAxisBinders(TiXmlElement* xmlControlNode) - { - TiXmlElement* xmlJoystickBinder = xmlControlNode->FirstChildElement("JoystickAxisBinder"); - while(xmlJoystickBinder) - { - Control::ControlChangingDirection dir = Control::STOP; - if(std::string(xmlJoystickBinder->Attribute("direction")) == "INCREASE") - { - dir = Control::INCREASE; - } - else if(std::string(xmlJoystickBinder->Attribute("direction")) == "DECREASE") - { - dir = Control::DECREASE; - } - - addJoystickAxisBinding(mControls.back(), FromString(xmlJoystickBinder->Attribute("deviceId")), FromString(xmlJoystickBinder->Attribute("axis")), dir); - - xmlJoystickBinder = xmlJoystickBinder->NextSiblingElement("JoystickAxisBinder"); - } - } - - void InputControlSystem::loadJoystickButtonBinders(TiXmlElement* xmlControlNode) - { - TiXmlElement* xmlJoystickButtonBinder = xmlControlNode->FirstChildElement("JoystickButtonBinder"); - while(xmlJoystickButtonBinder) - { - Control::ControlChangingDirection dir = Control::STOP; - if(std::string(xmlJoystickButtonBinder->Attribute("direction")) == "INCREASE") - { - dir = Control::INCREASE; - } - else if(std::string(xmlJoystickButtonBinder->Attribute("direction")) == "DECREASE") - { - dir = Control::DECREASE; - } - +/* ------------------------------------------------------- +Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the +Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions of +the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------- */ + +#include "ICSInputControlSystem.h" + +#define SDL_JOY_AXIS_MIN -32768 +#define SDL_JOY_AXIS_MAX 32767 + +namespace ICS +{ + // load xml + void InputControlSystem::loadJoystickAxisBinders(TiXmlElement* xmlControlNode) + { + TiXmlElement* xmlJoystickBinder = xmlControlNode->FirstChildElement("JoystickAxisBinder"); + while(xmlJoystickBinder) + { + Control::ControlChangingDirection dir = Control::STOP; + if(std::string(xmlJoystickBinder->Attribute("direction")) == "INCREASE") + { + dir = Control::INCREASE; + } + else if(std::string(xmlJoystickBinder->Attribute("direction")) == "DECREASE") + { + dir = Control::DECREASE; + } + + addJoystickAxisBinding(mControls.back(), FromString(xmlJoystickBinder->Attribute("deviceId")), FromString(xmlJoystickBinder->Attribute("axis")), dir); + + xmlJoystickBinder = xmlJoystickBinder->NextSiblingElement("JoystickAxisBinder"); + } + } + + void InputControlSystem::loadJoystickButtonBinders(TiXmlElement* xmlControlNode) + { + TiXmlElement* xmlJoystickButtonBinder = xmlControlNode->FirstChildElement("JoystickButtonBinder"); + while(xmlJoystickButtonBinder) + { + Control::ControlChangingDirection dir = Control::STOP; + if(std::string(xmlJoystickButtonBinder->Attribute("direction")) == "INCREASE") + { + dir = Control::INCREASE; + } + else if(std::string(xmlJoystickButtonBinder->Attribute("direction")) == "DECREASE") + { + dir = Control::DECREASE; + } + addJoystickButtonBinding(mControls.back(), FromString(xmlJoystickButtonBinder->Attribute("deviceId")), FromString(xmlJoystickButtonBinder->Attribute("button")), dir); - - xmlJoystickButtonBinder = xmlJoystickButtonBinder->NextSiblingElement("JoystickButtonBinder"); - } - } - - // add bindings - void InputControlSystem::addJoystickAxisBinding(Control* control, int deviceID, int axis, Control::ControlChangingDirection direction) - { - if (std::find(mJoystickIDList.begin(), mJoystickIDList.end(), deviceID) == mJoystickIDList.end()) - mJoystickIDList.push_back(deviceID); - - ICS_LOG("\tAdding AxisBinder [axis=" + + xmlJoystickButtonBinder = xmlJoystickButtonBinder->NextSiblingElement("JoystickButtonBinder"); + } + } + + // add bindings + void InputControlSystem::addJoystickAxisBinding(Control* control, int deviceID, int axis, Control::ControlChangingDirection direction) + { + if (std::find(mJoystickIDList.begin(), mJoystickIDList.end(), deviceID) == mJoystickIDList.end()) + mJoystickIDList.push_back(deviceID); + + ICS_LOG("\tAdding AxisBinder [axis=" + ToString(axis) + ", deviceID=" - + ToString(deviceID) + ", direction=" + + ToString(deviceID) + ", direction=" + ToString(direction) + "]"); - control->setValue(0.5f); //all joystick axis start at .5, so do that - - ControlAxisBinderItem controlAxisBinderItem; - controlAxisBinderItem.control = control; - controlAxisBinderItem.direction = direction; - mControlsJoystickAxisBinderMap[deviceID][axis] = controlAxisBinderItem; - } - - void InputControlSystem::addJoystickButtonBinding(Control* control, int deviceID, unsigned int button, Control::ControlChangingDirection direction) - { - if (std::find(mJoystickIDList.begin(), mJoystickIDList.end(), deviceID) == mJoystickIDList.end()) - mJoystickIDList.push_back(deviceID); // Hack: add the device to the list so bindings are saved in save() even when joystick is not connected - - ICS_LOG("\tAdding JoystickButtonBinder [button=" + control->setValue(0.5f); //all joystick axis start at .5, so do that + + ControlAxisBinderItem controlAxisBinderItem; + controlAxisBinderItem.control = control; + controlAxisBinderItem.direction = direction; + mControlsJoystickAxisBinderMap[deviceID][axis] = controlAxisBinderItem; + } + + void InputControlSystem::addJoystickButtonBinding(Control* control, int deviceID, unsigned int button, Control::ControlChangingDirection direction) + { + if (std::find(mJoystickIDList.begin(), mJoystickIDList.end(), deviceID) == mJoystickIDList.end()) + mJoystickIDList.push_back(deviceID); // Hack: add the device to the list so bindings are saved in save() even when joystick is not connected + + ICS_LOG("\tAdding JoystickButtonBinder [button=" + ToString(button) + ", deviceID=" - + ToString(deviceID) + ", direction=" - + ToString(direction) + "]"); - - ControlButtonBinderItem controlJoystickButtonBinderItem; - controlJoystickButtonBinderItem.direction = direction; - controlJoystickButtonBinderItem.control = control; - mControlsJoystickButtonBinderMap[deviceID][button] = controlJoystickButtonBinderItem; - } - - bool InputControlSystem::isJoystickButtonBound(int deviceID, unsigned int button) const - { - JoystickButtonBinderMapType::const_iterator found = mControlsJoystickButtonBinderMap.find(deviceID); - if (found == mControlsJoystickButtonBinderMap.end()) - return false; - - return (found->second.find(button) != found->second.end()); - } - - bool InputControlSystem::isJoystickAxisBound(int deviceID, unsigned int axis) const - { - JoystickAxisBinderMapType::const_iterator found = mControlsJoystickAxisBinderMap.find(deviceID); - if (found == mControlsJoystickAxisBinderMap.end()) - return false; - - return (found->second.find(axis) != found->second.end()); - } - - // get bindings - int InputControlSystem::getJoystickAxisBinding(Control* control, int deviceID, ICS::Control::ControlChangingDirection direction) + + ToString(deviceID) + ", direction=" + + ToString(direction) + "]"); + + ControlButtonBinderItem controlJoystickButtonBinderItem; + controlJoystickButtonBinderItem.direction = direction; + controlJoystickButtonBinderItem.control = control; + mControlsJoystickButtonBinderMap[deviceID][button] = controlJoystickButtonBinderItem; + } + + bool InputControlSystem::isJoystickButtonBound(int deviceID, unsigned int button) const + { + JoystickButtonBinderMapType::const_iterator found = mControlsJoystickButtonBinderMap.find(deviceID); + if (found == mControlsJoystickButtonBinderMap.end()) + return false; + + return (found->second.find(button) != found->second.end()); + } + + bool InputControlSystem::isJoystickAxisBound(int deviceID, unsigned int axis) const + { + JoystickAxisBinderMapType::const_iterator found = mControlsJoystickAxisBinderMap.find(deviceID); + if (found == mControlsJoystickAxisBinderMap.end()) + return false; + + return (found->second.find(axis) != found->second.end()); + } + + // get bindings + int InputControlSystem::getJoystickAxisBinding(Control* control, int deviceID, ICS::Control::ControlChangingDirection direction) { if(mControlsJoystickAxisBinderMap.find(deviceID) != mControlsJoystickAxisBinderMap.end()) - { - ControlsAxisBinderMapType::iterator it = mControlsJoystickAxisBinderMap[deviceID].begin(); - while(it != mControlsJoystickAxisBinderMap[deviceID].end()) - { - if(it->first >= 0 && it->second.control == control && it->second.direction == direction) - { - return it->first; - } - ++it; + { + ControlsAxisBinderMapType::iterator it = mControlsJoystickAxisBinderMap[deviceID].begin(); + while(it != mControlsJoystickAxisBinderMap[deviceID].end()) + { + if(it->first >= 0 && it->second.control == control && it->second.direction == direction) + { + return it->first; + } + ++it; } - } - - return /*NamedAxis::*/UNASSIGNED; - } - - unsigned int InputControlSystem::getJoystickButtonBinding(Control* control, int deviceID, ICS::Control::ControlChangingDirection direction) + } + + return /*NamedAxis::*/UNASSIGNED; + } + + unsigned int InputControlSystem::getJoystickButtonBinding(Control* control, int deviceID, ICS::Control::ControlChangingDirection direction) { if(mControlsJoystickButtonBinderMap.find(deviceID) != mControlsJoystickButtonBinderMap.end()) - { - ControlsButtonBinderMapType::iterator it = mControlsJoystickButtonBinderMap[deviceID].begin(); - while(it != mControlsJoystickButtonBinderMap[deviceID].end()) - { - if(it->second.control == control && it->second.direction == direction) - { - return it->first; - } - ++it; + { + ControlsButtonBinderMapType::iterator it = mControlsJoystickButtonBinderMap[deviceID].begin(); + while(it != mControlsJoystickButtonBinderMap[deviceID].end()) + { + if(it->second.control == control && it->second.direction == direction) + { + return it->first; + } + ++it; } - } - - return ICS_MAX_DEVICE_BUTTONS; - } - - // remove bindings - void InputControlSystem::removeJoystickAxisBinding(int deviceID, int axis) + } + + return ICS_MAX_DEVICE_BUTTONS; + } + + // remove bindings + void InputControlSystem::removeJoystickAxisBinding(int deviceID, int axis) { if(mControlsJoystickAxisBinderMap.find(deviceID) != mControlsJoystickAxisBinderMap.end()) - { - ControlsAxisBinderMapType::iterator it = mControlsJoystickAxisBinderMap[deviceID].find(axis); - if(it != mControlsJoystickAxisBinderMap[deviceID].end()) - { - mControlsJoystickAxisBinderMap[deviceID].erase(it); + { + ControlsAxisBinderMapType::iterator it = mControlsJoystickAxisBinderMap[deviceID].find(axis); + if(it != mControlsJoystickAxisBinderMap[deviceID].end()) + { + mControlsJoystickAxisBinderMap[deviceID].erase(it); } - } - } - - void InputControlSystem::removeJoystickButtonBinding(int deviceID, unsigned int button) + } + } + + void InputControlSystem::removeJoystickButtonBinding(int deviceID, unsigned int button) { if(mControlsJoystickButtonBinderMap.find(deviceID) != mControlsJoystickButtonBinderMap.end()) - { - ControlsButtonBinderMapType::iterator it = mControlsJoystickButtonBinderMap[deviceID].find(button); - if(it != mControlsJoystickButtonBinderMap[deviceID].end()) - { - mControlsJoystickButtonBinderMap[deviceID].erase(it); + { + ControlsButtonBinderMapType::iterator it = mControlsJoystickButtonBinderMap[deviceID].find(button); + if(it != mControlsJoystickButtonBinderMap[deviceID].end()) + { + mControlsJoystickButtonBinderMap[deviceID].erase(it); } - } - } - - // joyStick listeners - void InputControlSystem::buttonPressed(int deviceID, const SDL_ControllerButtonEvent &evt) - { - if(mActive) - { - if(!mDetectingBindingControl) + } + } + + // joyStick listeners + void InputControlSystem::buttonPressed(int deviceID, const SDL_ControllerButtonEvent &evt) + { + if(mActive) + { + if(!mDetectingBindingControl) { if(mControlsJoystickButtonBinderMap.find(deviceID) != mControlsJoystickButtonBinderMap.end()) - { - ControlsButtonBinderMapType::const_iterator it = mControlsJoystickButtonBinderMap[deviceID].find(evt.button); - if(it != mControlsJoystickButtonBinderMap[deviceID].end()) - { - it->second.control->setIgnoreAutoReverse(false); - if(!it->second.control->getAutoChangeDirectionOnLimitsAfterStop()) - { - it->second.control->setChangingDirection(it->second.direction); - } - else - { - if(it->second.control->getValue() == 1) - { - it->second.control->setChangingDirection(Control::DECREASE); - } - else if(it->second.control->getValue() == 0) - { - it->second.control->setChangingDirection(Control::INCREASE); - } - } + { + ControlsButtonBinderMapType::const_iterator it = mControlsJoystickButtonBinderMap[deviceID].find(evt.button); + if(it != mControlsJoystickButtonBinderMap[deviceID].end()) + { + it->second.control->setIgnoreAutoReverse(false); + if(!it->second.control->getAutoChangeDirectionOnLimitsAfterStop()) + { + it->second.control->setChangingDirection(it->second.direction); + } + else + { + if(it->second.control->getValue() == 1) + { + it->second.control->setChangingDirection(Control::DECREASE); + } + else if(it->second.control->getValue() == 0) + { + it->second.control->setChangingDirection(Control::INCREASE); + } + } } - } - } - } - } - - void InputControlSystem::buttonReleased(int deviceID, const SDL_ControllerButtonEvent &evt) - { - if(mActive) + } + } + } + } + + void InputControlSystem::buttonReleased(int deviceID, const SDL_ControllerButtonEvent &evt) + { + if(mActive) { if(!mDetectingBindingControl) { if(mControlsJoystickButtonBinderMap.find(deviceID) != mControlsJoystickButtonBinderMap.end()) - { - ControlsButtonBinderMapType::const_iterator it = mControlsJoystickButtonBinderMap[deviceID].find(evt.button); - if(it != mControlsJoystickButtonBinderMap[deviceID].end()) - { - it->second.control->setChangingDirection(Control::STOP); + { + ControlsButtonBinderMapType::const_iterator it = mControlsJoystickButtonBinderMap[deviceID].find(evt.button); + if(it != mControlsJoystickButtonBinderMap[deviceID].end()) + { + it->second.control->setChangingDirection(Control::STOP); } } } - else if(mDetectingBindingListener) - { - mDetectingBindingListener->joystickButtonBindingDetected(this, deviceID, - mDetectingBindingControl, evt.button, mDetectingBindingDirection); - } - } - } - - void InputControlSystem::axisMoved(int deviceID, const SDL_ControllerAxisEvent &evt) - { - if(mActive) - { - if(!mDetectingBindingControl) + else if(mDetectingBindingListener) + { + mDetectingBindingListener->joystickButtonBindingDetected(this, deviceID, + mDetectingBindingControl, evt.button, mDetectingBindingDirection); + } + } + } + + void InputControlSystem::axisMoved(int deviceID, const SDL_ControllerAxisEvent &evt) + { + if(mActive) + { + if(!mDetectingBindingControl) { if(mControlsJoystickAxisBinderMap.find(deviceID) != mControlsJoystickAxisBinderMap.end()) - { - ControlAxisBinderItem joystickBinderItem = mControlsJoystickAxisBinderMap[deviceID][evt.axis]; // joystic axis start at 0 index - Control* ctrl = joystickBinderItem.control; - if(ctrl) - { - ctrl->setIgnoreAutoReverse(true); - - float axisRange = SDL_JOY_AXIS_MAX - SDL_JOY_AXIS_MIN; + { + ControlAxisBinderItem joystickBinderItem = mControlsJoystickAxisBinderMap[deviceID][evt.axis]; // joystic axis start at 0 index + Control* ctrl = joystickBinderItem.control; + if(ctrl) + { + ctrl->setIgnoreAutoReverse(true); + + float axisRange = SDL_JOY_AXIS_MAX - SDL_JOY_AXIS_MIN; float valDisplaced = (float)(evt.value - SDL_JOY_AXIS_MIN); float percent = valDisplaced / axisRange * (1+mDeadZone*2) - mDeadZone; //Assures all values, 0 through 1, are seen if(percent > .5-mDeadZone && percent < .5+mDeadZone) //close enough to center @@ -268,57 +268,57 @@ namespace ICS else if(percent > .5) percent -= mDeadZone; else - percent += mDeadZone; - - if(joystickBinderItem.direction == Control::INCREASE) - { - ctrl->setValue( percent ); - } - else if(joystickBinderItem.direction == Control::DECREASE) - { - ctrl->setValue( 1 - ( percent ) ); - } + percent += mDeadZone; + + if(joystickBinderItem.direction == Control::INCREASE) + { + ctrl->setValue( percent ); + } + else if(joystickBinderItem.direction == Control::DECREASE) + { + ctrl->setValue( 1 - ( percent ) ); + } } - } - } - else if(mDetectingBindingListener) - { - //ControlAxisBinderItem joystickBinderItem = mControlsJoystickAxisBinderMap[ evt.which ][ axis ]; // joystic axis start at 0 index - //Control* ctrl = joystickBinderItem.control; - //if(ctrl && ctrl->isAxisBindable()) - if(mDetectingBindingControl->isAxisBindable()) - { - if( abs( evt.value ) > ICS_JOYSTICK_AXIS_BINDING_MARGIN) - { - mDetectingBindingListener->joystickAxisBindingDetected(this, deviceID, - mDetectingBindingControl, evt.axis, mDetectingBindingDirection); - } - } - } - } + } + } + else if(mDetectingBindingListener) + { + //ControlAxisBinderItem joystickBinderItem = mControlsJoystickAxisBinderMap[ evt.which ][ axis ]; // joystic axis start at 0 index + //Control* ctrl = joystickBinderItem.control; + //if(ctrl && ctrl->isAxisBindable()) + if(mDetectingBindingControl->isAxisBindable()) + { + if( abs( evt.value ) > ICS_JOYSTICK_AXIS_BINDING_MARGIN) + { + mDetectingBindingListener->joystickAxisBindingDetected(this, deviceID, + mDetectingBindingControl, evt.axis, mDetectingBindingDirection); + } + } + } + } } - void InputControlSystem::controllerAdded(int deviceID, const SDL_ControllerDeviceEvent &args) - { + void InputControlSystem::controllerAdded(int deviceID, const SDL_ControllerDeviceEvent &args) + { ICS_LOG("Adding joystick (index: " + ToString(args.which) + ")"); SDL_GameController* cntrl = SDL_GameControllerOpen(args.which); int instanceID = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(cntrl)); if(std::find(mJoystickIDList.begin(), mJoystickIDList.end(), deviceID)==mJoystickIDList.end()) - { - for(int j = 0 ; j < ICS_MAX_JOYSTICK_AXIS ; j++) - { - if(mControlsJoystickAxisBinderMap[deviceID].find(j) == mControlsJoystickAxisBinderMap[deviceID].end()) - { - ControlAxisBinderItem controlJoystickBinderItem; - controlJoystickBinderItem.direction = Control::STOP; - controlJoystickBinderItem.control = NULL; - mControlsJoystickAxisBinderMap[deviceID][j] = controlJoystickBinderItem; - } + { + for(int j = 0 ; j < ICS_MAX_JOYSTICK_AXIS ; j++) + { + if(mControlsJoystickAxisBinderMap[deviceID].find(j) == mControlsJoystickAxisBinderMap[deviceID].end()) + { + ControlAxisBinderItem controlJoystickBinderItem; + controlJoystickBinderItem.direction = Control::STOP; + controlJoystickBinderItem.control = NULL; + mControlsJoystickAxisBinderMap[deviceID][j] = controlJoystickBinderItem; + } } mJoystickIDList.push_front(deviceID); } - - mJoystickInstanceMap[instanceID] = cntrl; + + mJoystickInstanceMap[instanceID] = cntrl; } void InputControlSystem::controllerRemoved(const SDL_ControllerDeviceEvent &args) { @@ -328,38 +328,38 @@ namespace ICS SDL_GameControllerClose(mJoystickInstanceMap.at(args.which)); mJoystickInstanceMap.erase(args.which); } - } - - // joystick auto bindings - void DetectingBindingListener::joystickAxisBindingDetected(InputControlSystem* ICS, int deviceID, Control* control, int axis, Control::ControlChangingDirection direction) - { - // if the joystick axis is used by another control, remove it - ICS->removeJoystickAxisBinding(deviceID, axis); - - // if the control has an axis assigned, remove it - int oldAxis = ICS->getJoystickAxisBinding(control, deviceID, direction); - if(oldAxis != InputControlSystem::UNASSIGNED) - { - ICS->removeJoystickAxisBinding(deviceID, oldAxis); - } - - ICS->addJoystickAxisBinding(control, deviceID, axis, direction); - ICS->cancelDetectingBindingState(); - } - void DetectingBindingListener::joystickButtonBindingDetected(InputControlSystem* ICS, int deviceID, Control* control - , unsigned int button, Control::ControlChangingDirection direction) - { - // if the joystick button is used by another control, remove it - ICS->removeJoystickButtonBinding(deviceID, button); - - // if the control has a joystick button assigned, remove it - unsigned int oldButton = ICS->getJoystickButtonBinding(control, deviceID, direction); - if(oldButton != ICS_MAX_DEVICE_BUTTONS) - { - ICS->removeJoystickButtonBinding(deviceID, oldButton); - } - - ICS->addJoystickButtonBinding(control, deviceID, button, direction); - ICS->cancelDetectingBindingState(); - } -} + } + + // joystick auto bindings + void DetectingBindingListener::joystickAxisBindingDetected(InputControlSystem* ICS, int deviceID, Control* control, int axis, Control::ControlChangingDirection direction) + { + // if the joystick axis is used by another control, remove it + ICS->removeJoystickAxisBinding(deviceID, axis); + + // if the control has an axis assigned, remove it + int oldAxis = ICS->getJoystickAxisBinding(control, deviceID, direction); + if(oldAxis != InputControlSystem::UNASSIGNED) + { + ICS->removeJoystickAxisBinding(deviceID, oldAxis); + } + + ICS->addJoystickAxisBinding(control, deviceID, axis, direction); + ICS->cancelDetectingBindingState(); + } + void DetectingBindingListener::joystickButtonBindingDetected(InputControlSystem* ICS, int deviceID, Control* control + , unsigned int button, Control::ControlChangingDirection direction) + { + // if the joystick button is used by another control, remove it + ICS->removeJoystickButtonBinding(deviceID, button); + + // if the control has a joystick button assigned, remove it + unsigned int oldButton = ICS->getJoystickButtonBinding(control, deviceID, direction); + if(oldButton != ICS_MAX_DEVICE_BUTTONS) + { + ICS->removeJoystickButtonBinding(deviceID, oldButton); + } + + ICS->addJoystickButtonBinding(control, deviceID, button, direction); + ICS->cancelDetectingBindingState(); + } +} diff --git a/extern/oics/ICSInputControlSystem_keyboard.cpp b/extern/oics/ICSInputControlSystem_keyboard.cpp index ed35d9870d..34c3bf71d6 100644 --- a/extern/oics/ICSInputControlSystem_keyboard.cpp +++ b/extern/oics/ICSInputControlSystem_keyboard.cpp @@ -1,157 +1,157 @@ -/* ------------------------------------------------------- -Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the -Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions of -the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS -OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------- */ - -#include "ICSInputControlSystem.h" - -namespace ICS -{ - void InputControlSystem::loadKeyBinders(TiXmlElement* xmlControlNode) - { - TiXmlElement* xmlKeyBinder = xmlControlNode->FirstChildElement("KeyBinder"); - while(xmlKeyBinder) - { - Control::ControlChangingDirection dir = Control::STOP; - if(std::string(xmlKeyBinder->Attribute("direction")) == "INCREASE") - { - dir = Control::INCREASE; - } - else if(std::string(xmlKeyBinder->Attribute("direction")) == "DECREASE") - { - dir = Control::DECREASE; - } - - addKeyBinding(mControls.back(), SDL_Scancode(FromString(xmlKeyBinder->Attribute("key"))), dir); - - xmlKeyBinder = xmlKeyBinder->NextSiblingElement("KeyBinder"); - } - } - - void InputControlSystem::addKeyBinding(Control* control, SDL_Scancode key, Control::ControlChangingDirection direction) - { - ICS_LOG("\tAdding KeyBinder [key=" - + scancodeToString(key) + ", direction=" - + ToString(direction) + "]"); - - ControlKeyBinderItem controlKeyBinderItem; - controlKeyBinderItem.control = control; - controlKeyBinderItem.direction = direction; - mControlsKeyBinderMap[ key ] = controlKeyBinderItem; - } - - bool InputControlSystem::isKeyBound(SDL_Scancode key) const - { - return mControlsKeyBinderMap.find(key) != mControlsKeyBinderMap.end(); - } - - void InputControlSystem::removeKeyBinding(SDL_Scancode key) - { - ControlsKeyBinderMapType::iterator it = mControlsKeyBinderMap.find(key); - if(it != mControlsKeyBinderMap.end()) - { - mControlsKeyBinderMap.erase(it); - } - } - - SDL_Scancode InputControlSystem::getKeyBinding(Control* control - , ICS::Control::ControlChangingDirection direction) - { - ControlsKeyBinderMapType::iterator it = mControlsKeyBinderMap.begin(); - while(it != mControlsKeyBinderMap.end()) - { - if(it->second.control == control && it->second.direction == direction) - { - return it->first; - } - ++it; - } - - return SDL_SCANCODE_UNKNOWN; - } - void InputControlSystem::keyPressed(const SDL_KeyboardEvent &evt) - { - if(mActive) - { - if(!mDetectingBindingControl) - { - ControlsKeyBinderMapType::const_iterator it = mControlsKeyBinderMap.find(evt.keysym.scancode); - if(it != mControlsKeyBinderMap.end()) - { - it->second.control->setIgnoreAutoReverse(false); - if(!it->second.control->getAutoChangeDirectionOnLimitsAfterStop()) - { - it->second.control->setChangingDirection(it->second.direction); - } - else - { - if(it->second.control->getValue() == 1) - { - it->second.control->setChangingDirection(Control::DECREASE); - } - else if(it->second.control->getValue() == 0) - { - it->second.control->setChangingDirection(Control::INCREASE); - } - } - } - } - else if(mDetectingBindingListener) - { - mDetectingBindingListener->keyBindingDetected(this, - mDetectingBindingControl, evt.keysym.scancode, mDetectingBindingDirection); - } - } - } - - void InputControlSystem::keyReleased(const SDL_KeyboardEvent &evt) - { - if(mActive) - { - ControlsKeyBinderMapType::const_iterator it = mControlsKeyBinderMap.find(evt.keysym.scancode); - if(it != mControlsKeyBinderMap.end()) - { - it->second.control->setChangingDirection(Control::STOP); - } - } - } - - void DetectingBindingListener::keyBindingDetected(InputControlSystem* ICS, Control* control - , SDL_Scancode key, Control::ControlChangingDirection direction) - { - // if the key is used by another control, remove it - ICS->removeKeyBinding(key); - - // if the control has a key assigned, remove it - SDL_Scancode oldKey = ICS->getKeyBinding(control, direction); - if(oldKey != SDL_SCANCODE_UNKNOWN) - { - ICS->removeKeyBinding(oldKey); - } - - ICS->addKeyBinding(control, key, direction); - ICS->cancelDetectingBindingState(); - } - -} +/* ------------------------------------------------------- +Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the +Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions of +the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------- */ + +#include "ICSInputControlSystem.h" + +namespace ICS +{ + void InputControlSystem::loadKeyBinders(TiXmlElement* xmlControlNode) + { + TiXmlElement* xmlKeyBinder = xmlControlNode->FirstChildElement("KeyBinder"); + while(xmlKeyBinder) + { + Control::ControlChangingDirection dir = Control::STOP; + if(std::string(xmlKeyBinder->Attribute("direction")) == "INCREASE") + { + dir = Control::INCREASE; + } + else if(std::string(xmlKeyBinder->Attribute("direction")) == "DECREASE") + { + dir = Control::DECREASE; + } + + addKeyBinding(mControls.back(), SDL_Scancode(FromString(xmlKeyBinder->Attribute("key"))), dir); + + xmlKeyBinder = xmlKeyBinder->NextSiblingElement("KeyBinder"); + } + } + + void InputControlSystem::addKeyBinding(Control* control, SDL_Scancode key, Control::ControlChangingDirection direction) + { + ICS_LOG("\tAdding KeyBinder [key=" + + scancodeToString(key) + ", direction=" + + ToString(direction) + "]"); + + ControlKeyBinderItem controlKeyBinderItem; + controlKeyBinderItem.control = control; + controlKeyBinderItem.direction = direction; + mControlsKeyBinderMap[ key ] = controlKeyBinderItem; + } + + bool InputControlSystem::isKeyBound(SDL_Scancode key) const + { + return mControlsKeyBinderMap.find(key) != mControlsKeyBinderMap.end(); + } + + void InputControlSystem::removeKeyBinding(SDL_Scancode key) + { + ControlsKeyBinderMapType::iterator it = mControlsKeyBinderMap.find(key); + if(it != mControlsKeyBinderMap.end()) + { + mControlsKeyBinderMap.erase(it); + } + } + + SDL_Scancode InputControlSystem::getKeyBinding(Control* control + , ICS::Control::ControlChangingDirection direction) + { + ControlsKeyBinderMapType::iterator it = mControlsKeyBinderMap.begin(); + while(it != mControlsKeyBinderMap.end()) + { + if(it->second.control == control && it->second.direction == direction) + { + return it->first; + } + ++it; + } + + return SDL_SCANCODE_UNKNOWN; + } + void InputControlSystem::keyPressed(const SDL_KeyboardEvent &evt) + { + if(mActive) + { + if(!mDetectingBindingControl) + { + ControlsKeyBinderMapType::const_iterator it = mControlsKeyBinderMap.find(evt.keysym.scancode); + if(it != mControlsKeyBinderMap.end()) + { + it->second.control->setIgnoreAutoReverse(false); + if(!it->second.control->getAutoChangeDirectionOnLimitsAfterStop()) + { + it->second.control->setChangingDirection(it->second.direction); + } + else + { + if(it->second.control->getValue() == 1) + { + it->second.control->setChangingDirection(Control::DECREASE); + } + else if(it->second.control->getValue() == 0) + { + it->second.control->setChangingDirection(Control::INCREASE); + } + } + } + } + else if(mDetectingBindingListener) + { + mDetectingBindingListener->keyBindingDetected(this, + mDetectingBindingControl, evt.keysym.scancode, mDetectingBindingDirection); + } + } + } + + void InputControlSystem::keyReleased(const SDL_KeyboardEvent &evt) + { + if(mActive) + { + ControlsKeyBinderMapType::const_iterator it = mControlsKeyBinderMap.find(evt.keysym.scancode); + if(it != mControlsKeyBinderMap.end()) + { + it->second.control->setChangingDirection(Control::STOP); + } + } + } + + void DetectingBindingListener::keyBindingDetected(InputControlSystem* ICS, Control* control + , SDL_Scancode key, Control::ControlChangingDirection direction) + { + // if the key is used by another control, remove it + ICS->removeKeyBinding(key); + + // if the control has a key assigned, remove it + SDL_Scancode oldKey = ICS->getKeyBinding(control, direction); + if(oldKey != SDL_SCANCODE_UNKNOWN) + { + ICS->removeKeyBinding(oldKey); + } + + ICS->addKeyBinding(control, key, direction); + ICS->cancelDetectingBindingState(); + } + +} diff --git a/extern/oics/ICSInputControlSystem_mouse.cpp b/extern/oics/ICSInputControlSystem_mouse.cpp index 09404bfdd1..ab0c385fde 100644 --- a/extern/oics/ICSInputControlSystem_mouse.cpp +++ b/extern/oics/ICSInputControlSystem_mouse.cpp @@ -1,566 +1,566 @@ -/* ------------------------------------------------------- -Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the -Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions of -the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS -OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------- */ - -#include "ICSInputControlSystem.h" - -namespace ICS -{ - // load xml - void InputControlSystem::loadMouseAxisBinders(TiXmlElement* xmlControlNode) - { - TiXmlElement* xmlMouseBinder = xmlControlNode->FirstChildElement("MouseBinder"); - while(xmlMouseBinder) - { - Control::ControlChangingDirection dir = Control::STOP; - if(std::string(xmlMouseBinder->Attribute("direction")) == "INCREASE") - { - dir = Control::INCREASE; - } - else if(std::string(xmlMouseBinder->Attribute("direction")) == "DECREASE") - { - dir = Control::DECREASE; - } - - NamedAxis axis = /*NamedAxis::*/ X; - if((*xmlMouseBinder->Attribute("axis")) == 'Y') - { - axis = /*NamedAxis::*/ Y; - } - else if((*xmlMouseBinder->Attribute("axis")) == 'Z') - { - axis = /*NamedAxis::*/ Z; - } - - addMouseAxisBinding(mControls.back(), axis, dir); - - xmlMouseBinder = xmlMouseBinder->NextSiblingElement("MouseBinder"); - } - } - - void InputControlSystem::loadMouseButtonBinders(TiXmlElement* xmlControlNode) - { - TiXmlElement* xmlMouseButtonBinder = xmlControlNode->FirstChildElement("MouseButtonBinder"); - while(xmlMouseButtonBinder) - { - Control::ControlChangingDirection dir = Control::STOP; - if(std::string(xmlMouseButtonBinder->Attribute("direction")) == "INCREASE") - { - dir = Control::INCREASE; - } - else if(std::string(xmlMouseButtonBinder->Attribute("direction")) == "DECREASE") - { - dir = Control::DECREASE; - } - - int button = 0; - if(std::string(xmlMouseButtonBinder->Attribute("button")) == "LEFT") - { - button = SDL_BUTTON_LEFT; - } - else if(std::string(xmlMouseButtonBinder->Attribute("button")) == "RIGHT") - { - button = SDL_BUTTON_RIGHT; - } - else if(std::string(xmlMouseButtonBinder->Attribute("button")) == "MIDDLE") - { - button = SDL_BUTTON_MIDDLE; - } - else - { - button = FromString(xmlMouseButtonBinder->Attribute("button")); - } - - addMouseButtonBinding(mControls.back(), button, dir); - - xmlMouseButtonBinder = xmlMouseButtonBinder->NextSiblingElement("MouseButtonBinder"); - } - } - - - // add bindings - void InputControlSystem::addMouseAxisBinding(Control* control, NamedAxis axis, Control::ControlChangingDirection direction) - { - if(axis == /*NamedAxis::*/X) - { - mXmouseAxisBinded = true; - } - else if(axis == /*NamedAxis::*/Y) - { - mYmouseAxisBinded = true; - } - - addMouseAxisBinding_(control, axis, direction); - } - - /*protected*/ void InputControlSystem::addMouseAxisBinding_(Control* control, int axis, Control::ControlChangingDirection direction) - { - ICS_LOG("\tAdding AxisBinder [axis=" - + ToString(axis) + ", direction=" - + ToString(direction) + "]"); - - ControlAxisBinderItem controlAxisBinderItem; - controlAxisBinderItem.control = control; - controlAxisBinderItem.direction = direction; - mControlsMouseAxisBinderMap[ axis ] = controlAxisBinderItem; - } - - void InputControlSystem::addMouseButtonBinding(Control* control, unsigned int button, Control::ControlChangingDirection direction) - { - ICS_LOG("\tAdding MouseButtonBinder [button=" - + ToString(button) + ", direction=" - + ToString(direction) + "]"); - - ControlButtonBinderItem controlMouseButtonBinderItem; - controlMouseButtonBinderItem.direction = direction; - controlMouseButtonBinderItem.control = control; - mControlsMouseButtonBinderMap[ button ] = controlMouseButtonBinderItem; - } - - bool InputControlSystem::isMouseButtonBound(unsigned int button) const - { - return mControlsMouseButtonBinderMap.find(button) != mControlsMouseButtonBinderMap.end(); - } - - // get bindings - InputControlSystem::NamedAxis InputControlSystem::getMouseAxisBinding(Control* control, ICS::Control::ControlChangingDirection direction) - { - ControlsAxisBinderMapType::iterator it = mControlsMouseAxisBinderMap.begin(); - while(it != mControlsMouseAxisBinderMap.end()) - { - if(it->first < 0 && it->second.control == control && it->second.direction == direction) - { - return (InputControlSystem::NamedAxis)(it->first); - } - ++it; - } - - return /*NamedAxis::*/UNASSIGNED; - } - - //int InputControlSystem::getMouseAxisBinding(Control* control, ICS::Control::ControlChangingDirection direction) - //{ - // ControlsAxisBinderMapType::iterator it = mControlsMouseAxisBinderMap.begin(); - // while(it != mControlsMouseAxisBinderMap.end()) - // { - // if(it->first >= 0 && it->second.control == control && it->second.direction == direction) - // { - // return it->first; - // } - // it++; - // } - - // return /*NamedAxis::*/UNASSIGNED; - //} - - unsigned int InputControlSystem::getMouseButtonBinding(Control* control, ICS::Control::ControlChangingDirection direction) - { - ControlsButtonBinderMapType::iterator it = mControlsMouseButtonBinderMap.begin(); - while(it != mControlsMouseButtonBinderMap.end()) - { - if(it->second.control == control && it->second.direction == direction) - { - return it->first; - } - ++it; - } - - return ICS_MAX_DEVICE_BUTTONS; - } - - // remove bindings - void InputControlSystem::removeMouseAxisBinding(NamedAxis axis) - { - if(axis == /*NamedAxis::*/X) - { - mXmouseAxisBinded = false; - } - else if(axis == /*NamedAxis::*/Y) - { - mYmouseAxisBinded = false; - } - - removeMouseAxisBinding_(axis); - } - /*protected*/ void InputControlSystem::removeMouseAxisBinding_(int axis) - { - ControlsAxisBinderMapType::iterator it = mControlsMouseAxisBinderMap.find(axis); - if(it != mControlsMouseAxisBinderMap.end()) - { - mControlsMouseAxisBinderMap.erase(it); - } - } - - - void InputControlSystem::removeMouseButtonBinding(unsigned int button) - { - ControlsButtonBinderMapType::iterator it = mControlsMouseButtonBinderMap.find(button); - if(it != mControlsMouseButtonBinderMap.end()) - { - mControlsMouseButtonBinderMap.erase(it); - } - } - - // mouse Listeners - void InputControlSystem::mouseMoved(const SDL_MouseMotionEvent& evt) - { - if(mActive) - { - if(!mDetectingBindingControl) - { - if(mXmouseAxisBinded && evt.xrel) - { - ControlAxisBinderItem mouseBinderItem = mControlsMouseAxisBinderMap[ /*NamedAxis::*/X ]; - Control* ctrl = mouseBinderItem.control; - ctrl->setIgnoreAutoReverse(true); - if(mouseBinderItem.direction == Control::INCREASE) - { - ctrl->setValue( float( (evt.x) / float(mClientWidth) ) ); - } - else if(mouseBinderItem.direction == Control::DECREASE) - { - ctrl->setValue( 1 - float( evt.x / float(mClientWidth) ) ); - } - } - - if(mYmouseAxisBinded && evt.yrel) - { - ControlAxisBinderItem mouseBinderItem = mControlsMouseAxisBinderMap[ /*NamedAxis::*/Y ]; - Control* ctrl = mouseBinderItem.control; - ctrl->setIgnoreAutoReverse(true); - if(mouseBinderItem.direction == Control::INCREASE) - { - ctrl->setValue( float( (evt.y) / float(mClientHeight) ) ); - } - else if(mouseBinderItem.direction == Control::DECREASE) - { - ctrl->setValue( 1 - float( evt.y / float(mClientHeight) ) ); - } - } - - //! @todo Whats the range of the Z axis? - /*if(evt.state.Z.rel) - { - ControlAxisBinderItem mouseBinderItem = mControlsAxisBinderMap[ NamedAxis::Z ]; - Control* ctrl = mouseBinderItem.control; - ctrl->setIgnoreAutoReverse(true); - if(mouseBinderItem.direction == Control::INCREASE) - { - ctrl->setValue( float( (evt.state.Z.abs) / float(evt.state.¿width?) ) ); - } - else if(mouseBinderItem.direction == Control::DECREASE) - { - ctrl->setValue( float( (1 - evt.state.Z.abs) / float(evt.state.¿width?) ) ); - } - }*/ - } - else if(mDetectingBindingListener) - { - if(mDetectingBindingControl->isAxisBindable()) - { - if(mMouseAxisBindingInitialValues[0] == ICS_MOUSE_AXIS_BINDING_NULL_VALUE) - { - mMouseAxisBindingInitialValues[0] = 0; - mMouseAxisBindingInitialValues[1] = 0; - mMouseAxisBindingInitialValues[2] = 0; - } - - mMouseAxisBindingInitialValues[0] += evt.xrel; - mMouseAxisBindingInitialValues[1] += evt.yrel; - // mMouseAxisBindingInitialValues[2] += evt.zrel; - - if( abs(mMouseAxisBindingInitialValues[0]) > ICS_MOUSE_BINDING_MARGIN ) - { - mDetectingBindingListener->mouseAxisBindingDetected(this, - mDetectingBindingControl, X, mDetectingBindingDirection); - } - else if( abs(mMouseAxisBindingInitialValues[1]) > ICS_MOUSE_BINDING_MARGIN ) - { - mDetectingBindingListener->mouseAxisBindingDetected(this, - mDetectingBindingControl, Y, mDetectingBindingDirection); - } - else if( abs(mMouseAxisBindingInitialValues[2]) > ICS_MOUSE_BINDING_MARGIN ) - { - mDetectingBindingListener->mouseAxisBindingDetected(this, - mDetectingBindingControl, Z, mDetectingBindingDirection); - } - } - } - } - } - - void InputControlSystem::mousePressed(const SDL_MouseButtonEvent &evt, Uint8 btn) - { - if(mActive) - { - if(!mDetectingBindingControl) - { - ControlsButtonBinderMapType::const_iterator it = mControlsMouseButtonBinderMap.find((int)btn); - if(it != mControlsMouseButtonBinderMap.end()) - { - it->second.control->setIgnoreAutoReverse(false); - if(!it->second.control->getAutoChangeDirectionOnLimitsAfterStop()) - { - it->second.control->setChangingDirection(it->second.direction); - } - else - { - if(it->second.control->getValue() == 1) - { - it->second.control->setChangingDirection(Control::DECREASE); - } - else if(it->second.control->getValue() == 0) - { - it->second.control->setChangingDirection(Control::INCREASE); - } - } - } - } - } - } - - void InputControlSystem::mouseReleased(const SDL_MouseButtonEvent &evt, Uint8 btn) - { - if(mActive) - { - if (!mDetectingBindingControl) - { - ControlsButtonBinderMapType::const_iterator it = mControlsMouseButtonBinderMap.find((int)btn); - if(it != mControlsMouseButtonBinderMap.end()) - { - it->second.control->setChangingDirection(Control::STOP); - } - } - else if(mDetectingBindingListener) - { - mDetectingBindingListener->mouseButtonBindingDetected(this, - mDetectingBindingControl, btn, mDetectingBindingDirection); - } - } - } - - // mouse auto bindings - void DetectingBindingListener::mouseAxisBindingDetected(InputControlSystem* ICS, Control* control - , InputControlSystem::NamedAxis axis, Control::ControlChangingDirection direction) - { - // if the mouse axis is used by another control, remove it - ICS->removeMouseAxisBinding(axis); - - // if the control has an axis assigned, remove it - InputControlSystem::NamedAxis oldAxis = ICS->getMouseAxisBinding(control, direction); - if(oldAxis != InputControlSystem::UNASSIGNED) - { - ICS->removeMouseAxisBinding(oldAxis); - } - - ICS->addMouseAxisBinding(control, axis, direction); - ICS->cancelDetectingBindingState(); - } - - void DetectingBindingListener::mouseButtonBindingDetected(InputControlSystem* ICS, Control* control - , unsigned int button, Control::ControlChangingDirection direction) - { - // if the mouse button is used by another control, remove it - ICS->removeMouseButtonBinding(button); - - // if the control has a mouse button assigned, remove it - unsigned int oldButton = ICS->getMouseButtonBinding(control, direction); - if(oldButton != ICS_MAX_DEVICE_BUTTONS) - { - ICS->removeMouseButtonBinding(oldButton); - } - - ICS->addMouseButtonBinding(control, button, direction); - ICS->cancelDetectingBindingState(); - } - - /* ---------------------------------------------------------------------------------------- - * OPENMW CODE STARTS HERE - * Mouse Wheel support added by Michael Stopa (Stomy) */ - - void InputControlSystem::loadMouseWheelBinders(TiXmlElement* xmlControlNode) - { - TiXmlElement* xmlMouseWheelBinder = xmlControlNode->FirstChildElement("MouseWheelBinder"); - while (xmlMouseWheelBinder) - { - Control::ControlChangingDirection dir = Control::STOP; - if (std::string(xmlMouseWheelBinder->Attribute("direction")) == "INCREASE") - { - dir = Control::INCREASE; - } - else if (std::string(xmlMouseWheelBinder->Attribute("direction")) == "DECREASE") - { - dir = Control::DECREASE; - } - - MouseWheelClick click = MouseWheelClick::UNASSIGNED; - if (std::string(xmlMouseWheelBinder->Attribute("button")) == "UP") - { - click = MouseWheelClick::UP; - } - else if (std::string(xmlMouseWheelBinder->Attribute("button")) == "DOWN") - { - click = MouseWheelClick::DOWN; - } - else if (std::string(xmlMouseWheelBinder->Attribute("button")) == "DOWN") - { - click = MouseWheelClick::RIGHT; - } - else if (std::string(xmlMouseWheelBinder->Attribute("button")) == "DOWN") - { - click = MouseWheelClick::LEFT; - } - - addMouseWheelBinding(mControls.back(), click, dir); - xmlMouseWheelBinder = xmlMouseWheelBinder->NextSiblingElement("MouseWheelBinder"); - } - } - - void InputControlSystem::addMouseWheelBinding( - Control* control, - MouseWheelClick click, - Control::ControlChangingDirection direction) - { - ICS_LOG("\tAdding MouseWheelBinder [button=" - + ToString(static_cast(click)) + ", direction=" - + ToString(direction) + "]"); - - ControlButtonBinderItem controlButtonBinderItem; - controlButtonBinderItem.control = control; - controlButtonBinderItem.direction = direction; - mControlsMouseWheelBinderMap[static_cast(click)] = controlButtonBinderItem; - } - - void InputControlSystem::removeMouseWheelBinding(MouseWheelClick click) - { - ControlsAxisBinderMapType::iterator it = mControlsMouseWheelBinderMap.find(static_cast(click)); - if (it != mControlsMouseWheelBinderMap.end()) - { - mControlsMouseWheelBinderMap.erase(it); - } - } - - InputControlSystem::MouseWheelClick InputControlSystem::getMouseWheelBinding( - Control* control, - ICS::Control::ControlChangingDirection direction) - { - ControlsAxisBinderMapType::iterator it = mControlsMouseWheelBinderMap.begin(); - while (it != mControlsMouseWheelBinderMap.end()) - { - if (it->first > 0 && it->second.control == control && it->second.direction == direction) - { - return (MouseWheelClick)(it->first); - } - ++it; - } - - return MouseWheelClick::UNASSIGNED; - } - - bool InputControlSystem::isMouseWheelBound(MouseWheelClick button) const - { - return mControlsMouseWheelBinderMap.find(static_cast(button)) != mControlsMouseWheelBinderMap.end(); - } - - void InputControlSystem::mouseWheelMoved(const SDL_MouseWheelEvent &evt) - { - if (mActive) - { - MouseWheelClick click = MouseWheelClick::UNASSIGNED; - int value; - if (evt.y != 0) - { - value = evt.y; - if (evt.direction == SDL_MOUSEWHEEL_FLIPPED) - value *= -1; - if (value > 0) - click = MouseWheelClick::UP; - else - click = MouseWheelClick::DOWN; - } - else if (evt.x != 0) - { - value = evt.x; - if (evt.direction == SDL_MOUSEWHEEL_FLIPPED) - value *= -1; - if (value > 0) - click = MouseWheelClick::RIGHT; - else - click = MouseWheelClick::LEFT; - } - else - return; - - if(!mDetectingBindingControl) - { - // This assumes a single event is sent for every single mouse wheel direction, if they are - // buffered up then all bindings will have to be resolved on every invocation of this function - - ControlButtonBinderItem wheelBinderItem = mControlsMouseWheelBinderMap[static_cast(click)]; - Control* control = wheelBinderItem.control; - if (control) - { - control->setIgnoreAutoReverse(false); - if (wheelBinderItem.direction == Control::INCREASE) - { - control->setValue(static_cast(std::abs(value))); - control->setChangingDirection(Control::STOP); - } - else if (wheelBinderItem.direction == Control::DECREASE) - { - control->setValue(static_cast(std::abs(value))); - control->setChangingDirection(Control::STOP); - } - } - } - else if(mDetectingBindingListener) - { - mDetectingBindingListener->mouseWheelBindingDetected(this, - mDetectingBindingControl, click, mDetectingBindingDirection); - } - } - } - - void DetectingBindingListener::mouseWheelBindingDetected( - InputControlSystem* ICS, - Control* control, - InputControlSystem::MouseWheelClick click, - Control::ControlChangingDirection direction) - { - ICS->removeMouseWheelBinding(click); - - InputControlSystem::MouseWheelClick oldClick = ICS->getMouseWheelBinding(control, direction); - if (oldClick != InputControlSystem::MouseWheelClick::UNASSIGNED) - { - ICS->removeMouseWheelBinding(oldClick); - } - - ICS->addMouseWheelBinding(control, click, direction); - ICS->cancelDetectingBindingState(); - } - - /* OPENMW CODE ENDS HERE - * ------------------------------------------------------------------------------------- */ -} +/* ------------------------------------------------------- +Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the +Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions of +the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------- */ + +#include "ICSInputControlSystem.h" + +namespace ICS +{ + // load xml + void InputControlSystem::loadMouseAxisBinders(TiXmlElement* xmlControlNode) + { + TiXmlElement* xmlMouseBinder = xmlControlNode->FirstChildElement("MouseBinder"); + while(xmlMouseBinder) + { + Control::ControlChangingDirection dir = Control::STOP; + if(std::string(xmlMouseBinder->Attribute("direction")) == "INCREASE") + { + dir = Control::INCREASE; + } + else if(std::string(xmlMouseBinder->Attribute("direction")) == "DECREASE") + { + dir = Control::DECREASE; + } + + NamedAxis axis = /*NamedAxis::*/ X; + if((*xmlMouseBinder->Attribute("axis")) == 'Y') + { + axis = /*NamedAxis::*/ Y; + } + else if((*xmlMouseBinder->Attribute("axis")) == 'Z') + { + axis = /*NamedAxis::*/ Z; + } + + addMouseAxisBinding(mControls.back(), axis, dir); + + xmlMouseBinder = xmlMouseBinder->NextSiblingElement("MouseBinder"); + } + } + + void InputControlSystem::loadMouseButtonBinders(TiXmlElement* xmlControlNode) + { + TiXmlElement* xmlMouseButtonBinder = xmlControlNode->FirstChildElement("MouseButtonBinder"); + while(xmlMouseButtonBinder) + { + Control::ControlChangingDirection dir = Control::STOP; + if(std::string(xmlMouseButtonBinder->Attribute("direction")) == "INCREASE") + { + dir = Control::INCREASE; + } + else if(std::string(xmlMouseButtonBinder->Attribute("direction")) == "DECREASE") + { + dir = Control::DECREASE; + } + + int button = 0; + if(std::string(xmlMouseButtonBinder->Attribute("button")) == "LEFT") + { + button = SDL_BUTTON_LEFT; + } + else if(std::string(xmlMouseButtonBinder->Attribute("button")) == "RIGHT") + { + button = SDL_BUTTON_RIGHT; + } + else if(std::string(xmlMouseButtonBinder->Attribute("button")) == "MIDDLE") + { + button = SDL_BUTTON_MIDDLE; + } + else + { + button = FromString(xmlMouseButtonBinder->Attribute("button")); + } + + addMouseButtonBinding(mControls.back(), button, dir); + + xmlMouseButtonBinder = xmlMouseButtonBinder->NextSiblingElement("MouseButtonBinder"); + } + } + + + // add bindings + void InputControlSystem::addMouseAxisBinding(Control* control, NamedAxis axis, Control::ControlChangingDirection direction) + { + if(axis == /*NamedAxis::*/X) + { + mXmouseAxisBinded = true; + } + else if(axis == /*NamedAxis::*/Y) + { + mYmouseAxisBinded = true; + } + + addMouseAxisBinding_(control, axis, direction); + } + + /*protected*/ void InputControlSystem::addMouseAxisBinding_(Control* control, int axis, Control::ControlChangingDirection direction) + { + ICS_LOG("\tAdding AxisBinder [axis=" + + ToString(axis) + ", direction=" + + ToString(direction) + "]"); + + ControlAxisBinderItem controlAxisBinderItem; + controlAxisBinderItem.control = control; + controlAxisBinderItem.direction = direction; + mControlsMouseAxisBinderMap[ axis ] = controlAxisBinderItem; + } + + void InputControlSystem::addMouseButtonBinding(Control* control, unsigned int button, Control::ControlChangingDirection direction) + { + ICS_LOG("\tAdding MouseButtonBinder [button=" + + ToString(button) + ", direction=" + + ToString(direction) + "]"); + + ControlButtonBinderItem controlMouseButtonBinderItem; + controlMouseButtonBinderItem.direction = direction; + controlMouseButtonBinderItem.control = control; + mControlsMouseButtonBinderMap[ button ] = controlMouseButtonBinderItem; + } + + bool InputControlSystem::isMouseButtonBound(unsigned int button) const + { + return mControlsMouseButtonBinderMap.find(button) != mControlsMouseButtonBinderMap.end(); + } + + // get bindings + InputControlSystem::NamedAxis InputControlSystem::getMouseAxisBinding(Control* control, ICS::Control::ControlChangingDirection direction) + { + ControlsAxisBinderMapType::iterator it = mControlsMouseAxisBinderMap.begin(); + while(it != mControlsMouseAxisBinderMap.end()) + { + if(it->first < 0 && it->second.control == control && it->second.direction == direction) + { + return (InputControlSystem::NamedAxis)(it->first); + } + ++it; + } + + return /*NamedAxis::*/UNASSIGNED; + } + + //int InputControlSystem::getMouseAxisBinding(Control* control, ICS::Control::ControlChangingDirection direction) + //{ + // ControlsAxisBinderMapType::iterator it = mControlsMouseAxisBinderMap.begin(); + // while(it != mControlsMouseAxisBinderMap.end()) + // { + // if(it->first >= 0 && it->second.control == control && it->second.direction == direction) + // { + // return it->first; + // } + // it++; + // } + + // return /*NamedAxis::*/UNASSIGNED; + //} + + unsigned int InputControlSystem::getMouseButtonBinding(Control* control, ICS::Control::ControlChangingDirection direction) + { + ControlsButtonBinderMapType::iterator it = mControlsMouseButtonBinderMap.begin(); + while(it != mControlsMouseButtonBinderMap.end()) + { + if(it->second.control == control && it->second.direction == direction) + { + return it->first; + } + ++it; + } + + return ICS_MAX_DEVICE_BUTTONS; + } + + // remove bindings + void InputControlSystem::removeMouseAxisBinding(NamedAxis axis) + { + if(axis == /*NamedAxis::*/X) + { + mXmouseAxisBinded = false; + } + else if(axis == /*NamedAxis::*/Y) + { + mYmouseAxisBinded = false; + } + + removeMouseAxisBinding_(axis); + } + /*protected*/ void InputControlSystem::removeMouseAxisBinding_(int axis) + { + ControlsAxisBinderMapType::iterator it = mControlsMouseAxisBinderMap.find(axis); + if(it != mControlsMouseAxisBinderMap.end()) + { + mControlsMouseAxisBinderMap.erase(it); + } + } + + + void InputControlSystem::removeMouseButtonBinding(unsigned int button) + { + ControlsButtonBinderMapType::iterator it = mControlsMouseButtonBinderMap.find(button); + if(it != mControlsMouseButtonBinderMap.end()) + { + mControlsMouseButtonBinderMap.erase(it); + } + } + + // mouse Listeners + void InputControlSystem::mouseMoved(const SDL_MouseMotionEvent& evt) + { + if(mActive) + { + if(!mDetectingBindingControl) + { + if(mXmouseAxisBinded && evt.xrel) + { + ControlAxisBinderItem mouseBinderItem = mControlsMouseAxisBinderMap[ /*NamedAxis::*/X ]; + Control* ctrl = mouseBinderItem.control; + ctrl->setIgnoreAutoReverse(true); + if(mouseBinderItem.direction == Control::INCREASE) + { + ctrl->setValue( float( (evt.x) / float(mClientWidth) ) ); + } + else if(mouseBinderItem.direction == Control::DECREASE) + { + ctrl->setValue( 1 - float( evt.x / float(mClientWidth) ) ); + } + } + + if(mYmouseAxisBinded && evt.yrel) + { + ControlAxisBinderItem mouseBinderItem = mControlsMouseAxisBinderMap[ /*NamedAxis::*/Y ]; + Control* ctrl = mouseBinderItem.control; + ctrl->setIgnoreAutoReverse(true); + if(mouseBinderItem.direction == Control::INCREASE) + { + ctrl->setValue( float( (evt.y) / float(mClientHeight) ) ); + } + else if(mouseBinderItem.direction == Control::DECREASE) + { + ctrl->setValue( 1 - float( evt.y / float(mClientHeight) ) ); + } + } + + //! @todo Whats the range of the Z axis? + /*if(evt.state.Z.rel) + { + ControlAxisBinderItem mouseBinderItem = mControlsAxisBinderMap[ NamedAxis::Z ]; + Control* ctrl = mouseBinderItem.control; + ctrl->setIgnoreAutoReverse(true); + if(mouseBinderItem.direction == Control::INCREASE) + { + ctrl->setValue( float( (evt.state.Z.abs) / float(evt.state.¿width?) ) ); + } + else if(mouseBinderItem.direction == Control::DECREASE) + { + ctrl->setValue( float( (1 - evt.state.Z.abs) / float(evt.state.¿width?) ) ); + } + }*/ + } + else if(mDetectingBindingListener) + { + if(mDetectingBindingControl->isAxisBindable()) + { + if(mMouseAxisBindingInitialValues[0] == ICS_MOUSE_AXIS_BINDING_NULL_VALUE) + { + mMouseAxisBindingInitialValues[0] = 0; + mMouseAxisBindingInitialValues[1] = 0; + mMouseAxisBindingInitialValues[2] = 0; + } + + mMouseAxisBindingInitialValues[0] += evt.xrel; + mMouseAxisBindingInitialValues[1] += evt.yrel; + // mMouseAxisBindingInitialValues[2] += evt.zrel; + + if( abs(mMouseAxisBindingInitialValues[0]) > ICS_MOUSE_BINDING_MARGIN ) + { + mDetectingBindingListener->mouseAxisBindingDetected(this, + mDetectingBindingControl, X, mDetectingBindingDirection); + } + else if( abs(mMouseAxisBindingInitialValues[1]) > ICS_MOUSE_BINDING_MARGIN ) + { + mDetectingBindingListener->mouseAxisBindingDetected(this, + mDetectingBindingControl, Y, mDetectingBindingDirection); + } + else if( abs(mMouseAxisBindingInitialValues[2]) > ICS_MOUSE_BINDING_MARGIN ) + { + mDetectingBindingListener->mouseAxisBindingDetected(this, + mDetectingBindingControl, Z, mDetectingBindingDirection); + } + } + } + } + } + + void InputControlSystem::mousePressed(const SDL_MouseButtonEvent &evt, Uint8 btn) + { + if(mActive) + { + if(!mDetectingBindingControl) + { + ControlsButtonBinderMapType::const_iterator it = mControlsMouseButtonBinderMap.find((int)btn); + if(it != mControlsMouseButtonBinderMap.end()) + { + it->second.control->setIgnoreAutoReverse(false); + if(!it->second.control->getAutoChangeDirectionOnLimitsAfterStop()) + { + it->second.control->setChangingDirection(it->second.direction); + } + else + { + if(it->second.control->getValue() == 1) + { + it->second.control->setChangingDirection(Control::DECREASE); + } + else if(it->second.control->getValue() == 0) + { + it->second.control->setChangingDirection(Control::INCREASE); + } + } + } + } + } + } + + void InputControlSystem::mouseReleased(const SDL_MouseButtonEvent &evt, Uint8 btn) + { + if(mActive) + { + if (!mDetectingBindingControl) + { + ControlsButtonBinderMapType::const_iterator it = mControlsMouseButtonBinderMap.find((int)btn); + if(it != mControlsMouseButtonBinderMap.end()) + { + it->second.control->setChangingDirection(Control::STOP); + } + } + else if(mDetectingBindingListener) + { + mDetectingBindingListener->mouseButtonBindingDetected(this, + mDetectingBindingControl, btn, mDetectingBindingDirection); + } + } + } + + // mouse auto bindings + void DetectingBindingListener::mouseAxisBindingDetected(InputControlSystem* ICS, Control* control + , InputControlSystem::NamedAxis axis, Control::ControlChangingDirection direction) + { + // if the mouse axis is used by another control, remove it + ICS->removeMouseAxisBinding(axis); + + // if the control has an axis assigned, remove it + InputControlSystem::NamedAxis oldAxis = ICS->getMouseAxisBinding(control, direction); + if(oldAxis != InputControlSystem::UNASSIGNED) + { + ICS->removeMouseAxisBinding(oldAxis); + } + + ICS->addMouseAxisBinding(control, axis, direction); + ICS->cancelDetectingBindingState(); + } + + void DetectingBindingListener::mouseButtonBindingDetected(InputControlSystem* ICS, Control* control + , unsigned int button, Control::ControlChangingDirection direction) + { + // if the mouse button is used by another control, remove it + ICS->removeMouseButtonBinding(button); + + // if the control has a mouse button assigned, remove it + unsigned int oldButton = ICS->getMouseButtonBinding(control, direction); + if(oldButton != ICS_MAX_DEVICE_BUTTONS) + { + ICS->removeMouseButtonBinding(oldButton); + } + + ICS->addMouseButtonBinding(control, button, direction); + ICS->cancelDetectingBindingState(); + } + + /* ---------------------------------------------------------------------------------------- + * OPENMW CODE STARTS HERE + * Mouse Wheel support added by Michael Stopa (Stomy) */ + + void InputControlSystem::loadMouseWheelBinders(TiXmlElement* xmlControlNode) + { + TiXmlElement* xmlMouseWheelBinder = xmlControlNode->FirstChildElement("MouseWheelBinder"); + while (xmlMouseWheelBinder) + { + Control::ControlChangingDirection dir = Control::STOP; + if (std::string(xmlMouseWheelBinder->Attribute("direction")) == "INCREASE") + { + dir = Control::INCREASE; + } + else if (std::string(xmlMouseWheelBinder->Attribute("direction")) == "DECREASE") + { + dir = Control::DECREASE; + } + + MouseWheelClick click = MouseWheelClick::UNASSIGNED; + if (std::string(xmlMouseWheelBinder->Attribute("button")) == "UP") + { + click = MouseWheelClick::UP; + } + else if (std::string(xmlMouseWheelBinder->Attribute("button")) == "DOWN") + { + click = MouseWheelClick::DOWN; + } + else if (std::string(xmlMouseWheelBinder->Attribute("button")) == "DOWN") + { + click = MouseWheelClick::RIGHT; + } + else if (std::string(xmlMouseWheelBinder->Attribute("button")) == "DOWN") + { + click = MouseWheelClick::LEFT; + } + + addMouseWheelBinding(mControls.back(), click, dir); + xmlMouseWheelBinder = xmlMouseWheelBinder->NextSiblingElement("MouseWheelBinder"); + } + } + + void InputControlSystem::addMouseWheelBinding( + Control* control, + MouseWheelClick click, + Control::ControlChangingDirection direction) + { + ICS_LOG("\tAdding MouseWheelBinder [button=" + + ToString(static_cast(click)) + ", direction=" + + ToString(direction) + "]"); + + ControlButtonBinderItem controlButtonBinderItem; + controlButtonBinderItem.control = control; + controlButtonBinderItem.direction = direction; + mControlsMouseWheelBinderMap[static_cast(click)] = controlButtonBinderItem; + } + + void InputControlSystem::removeMouseWheelBinding(MouseWheelClick click) + { + ControlsAxisBinderMapType::iterator it = mControlsMouseWheelBinderMap.find(static_cast(click)); + if (it != mControlsMouseWheelBinderMap.end()) + { + mControlsMouseWheelBinderMap.erase(it); + } + } + + InputControlSystem::MouseWheelClick InputControlSystem::getMouseWheelBinding( + Control* control, + ICS::Control::ControlChangingDirection direction) + { + ControlsAxisBinderMapType::iterator it = mControlsMouseWheelBinderMap.begin(); + while (it != mControlsMouseWheelBinderMap.end()) + { + if (it->first > 0 && it->second.control == control && it->second.direction == direction) + { + return (MouseWheelClick)(it->first); + } + ++it; + } + + return MouseWheelClick::UNASSIGNED; + } + + bool InputControlSystem::isMouseWheelBound(MouseWheelClick button) const + { + return mControlsMouseWheelBinderMap.find(static_cast(button)) != mControlsMouseWheelBinderMap.end(); + } + + void InputControlSystem::mouseWheelMoved(const SDL_MouseWheelEvent &evt) + { + if (mActive) + { + MouseWheelClick click = MouseWheelClick::UNASSIGNED; + int value; + if (evt.y != 0) + { + value = evt.y; + if (evt.direction == SDL_MOUSEWHEEL_FLIPPED) + value *= -1; + if (value > 0) + click = MouseWheelClick::UP; + else + click = MouseWheelClick::DOWN; + } + else if (evt.x != 0) + { + value = evt.x; + if (evt.direction == SDL_MOUSEWHEEL_FLIPPED) + value *= -1; + if (value > 0) + click = MouseWheelClick::RIGHT; + else + click = MouseWheelClick::LEFT; + } + else + return; + + if(!mDetectingBindingControl) + { + // This assumes a single event is sent for every single mouse wheel direction, if they are + // buffered up then all bindings will have to be resolved on every invocation of this function + + ControlButtonBinderItem wheelBinderItem = mControlsMouseWheelBinderMap[static_cast(click)]; + Control* control = wheelBinderItem.control; + if (control) + { + control->setIgnoreAutoReverse(false); + if (wheelBinderItem.direction == Control::INCREASE) + { + control->setValue(static_cast(std::abs(value))); + control->setChangingDirection(Control::STOP); + } + else if (wheelBinderItem.direction == Control::DECREASE) + { + control->setValue(static_cast(std::abs(value))); + control->setChangingDirection(Control::STOP); + } + } + } + else if(mDetectingBindingListener) + { + mDetectingBindingListener->mouseWheelBindingDetected(this, + mDetectingBindingControl, click, mDetectingBindingDirection); + } + } + } + + void DetectingBindingListener::mouseWheelBindingDetected( + InputControlSystem* ICS, + Control* control, + InputControlSystem::MouseWheelClick click, + Control::ControlChangingDirection direction) + { + ICS->removeMouseWheelBinding(click); + + InputControlSystem::MouseWheelClick oldClick = ICS->getMouseWheelBinding(control, direction); + if (oldClick != InputControlSystem::MouseWheelClick::UNASSIGNED) + { + ICS->removeMouseWheelBinding(oldClick); + } + + ICS->addMouseWheelBinding(control, click, direction); + ICS->cancelDetectingBindingState(); + } + + /* OPENMW CODE ENDS HERE + * ------------------------------------------------------------------------------------- */ +} diff --git a/extern/oics/ICSPrerequisites.cpp b/extern/oics/ICSPrerequisites.cpp index 2824950ed1..c1bec8b8c8 100644 --- a/extern/oics/ICSPrerequisites.cpp +++ b/extern/oics/ICSPrerequisites.cpp @@ -1,27 +1,27 @@ -/* ------------------------------------------------------- -Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the -Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions of -the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS -OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------- */ - -#include "ICSPrerequisites.h" +/* ------------------------------------------------------- +Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the +Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions of +the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------- */ + +#include "ICSPrerequisites.h" diff --git a/extern/oics/ICSPrerequisites.h b/extern/oics/ICSPrerequisites.h index ed99f4f54f..75aa9347bb 100644 --- a/extern/oics/ICSPrerequisites.h +++ b/extern/oics/ICSPrerequisites.h @@ -1,110 +1,110 @@ -/* ------------------------------------------------------- -Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the -Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions of -the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS -OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------- */ - -//! @todo add mouse wheel support - -#ifndef _InputControlSystem_Prerequisites_H_ -#define _InputControlSystem_Prerequisites_H_ - -/// Include external headers -#include -#include -#include -#include -#include -#include -#include /* std::min and std::max for MSVC 2013 */ - -#include "tinyxml.h" - -#include "SDL_keyboard.h" -#include "SDL_mouse.h" -#include "SDL_joystick.h" -#include "SDL_events.h" - -/// Define the dll export qualifier if compiling for Windows - -/* -#ifdef ICS_PLATFORM_WIN32 - #ifdef ICS_LIB - #define DllExport __declspec (dllexport) - #else - #define DllExport __declspec (dllimport) - #endif -#else - #define DllExport -#endif -*/ -#define DllExport - -// Define some macros -#define ICS_DEPRECATED __declspec(deprecated("Deprecated. It will be removed in future versions.")) - -/// Version defines -#define ICS_VERSION_MAJOR 0 -#define ICS_VERSION_MINOR 4 -#define ICS_VERSION_PATCH 0 - -#define ICS_MAX_DEVICE_BUTTONS 30 - -namespace ICS -{ - template - bool StringIsNumber ( const std::string &Text ) - { - std::stringstream ss(Text); - T result; - return (ss >> result) ? true : false; - } - - // from http://www.cplusplus.com/forum/articles/9645/ - template - std::string ToString ( T value ) - { - std::stringstream ss; - ss << value; - return ss.str(); - } - - // from http://www.cplusplus.com/forum/articles/9645/ - template - T FromString ( const std::string &Text )//Text not by const reference so that the function can be used with a - { //character array as argument - std::stringstream ss(Text); - T result; - return (ss >> result) ? result : 0; - } - - class InputControlSystem; - class Channel; - class ChannelListener; - class Control; - class ControlListener; - class DetectingBindingListener; - class InputControlSystemLog; -} - -#endif +/* ------------------------------------------------------- +Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es) + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the +Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions of +the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------- */ + +//! @todo add mouse wheel support + +#ifndef _InputControlSystem_Prerequisites_H_ +#define _InputControlSystem_Prerequisites_H_ + +/// Include external headers +#include +#include +#include +#include +#include +#include +#include /* std::min and std::max for MSVC 2013 */ + +#include "tinyxml.h" + +#include "SDL_keyboard.h" +#include "SDL_mouse.h" +#include "SDL_joystick.h" +#include "SDL_events.h" + +/// Define the dll export qualifier if compiling for Windows + +/* +#ifdef ICS_PLATFORM_WIN32 + #ifdef ICS_LIB + #define DllExport __declspec (dllexport) + #else + #define DllExport __declspec (dllimport) + #endif +#else + #define DllExport +#endif +*/ +#define DllExport + +// Define some macros +#define ICS_DEPRECATED __declspec(deprecated("Deprecated. It will be removed in future versions.")) + +/// Version defines +#define ICS_VERSION_MAJOR 0 +#define ICS_VERSION_MINOR 4 +#define ICS_VERSION_PATCH 0 + +#define ICS_MAX_DEVICE_BUTTONS 30 + +namespace ICS +{ + template + bool StringIsNumber ( const std::string &Text ) + { + std::stringstream ss(Text); + T result; + return (ss >> result) ? true : false; + } + + // from http://www.cplusplus.com/forum/articles/9645/ + template + std::string ToString ( T value ) + { + std::stringstream ss; + ss << value; + return ss.str(); + } + + // from http://www.cplusplus.com/forum/articles/9645/ + template + T FromString ( const std::string &Text )//Text not by const reference so that the function can be used with a + { //character array as argument + std::stringstream ss(Text); + T result; + return (ss >> result) ? result : 0; + } + + class InputControlSystem; + class Channel; + class ChannelListener; + class Control; + class ControlListener; + class DetectingBindingListener; + class InputControlSystemLog; +} + +#endif diff --git a/extern/sol3/sol/assert.hpp b/extern/sol3/sol/assert.hpp index 860ac3deee..e46b9f122a 100644 --- a/extern/sol3/sol/assert.hpp +++ b/extern/sol3/sol/assert.hpp @@ -1,99 +1,99 @@ -// sol2 - -// The MIT License (MIT) - -// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors - -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -#pragma once - -#ifndef SOL_ASSERT_HPP -#define SOL_ASSERT_HPP - -#include - -#if SOL_IS_ON(SOL2_CI_I_) - -struct pre_main { - pre_main() { -#ifdef _MSC_VER - _set_abort_behavior(0, _WRITE_ABORT_MSG); -#endif - } -} inline sol2_ci_dont_lock_ci_please = {}; - -#endif // Prevent lockup when doing Continuous Integration - - -// clang-format off - -#if SOL_IS_ON(SOL_USER_C_ASSERT_I_) - #define sol_c_assert(...) SOL_C_ASSERT(__VA_ARGS__) -#else - #if SOL_IS_ON(SOL_DEBUG_BUILD_I_) - #include - #include - #include - - #define sol_c_assert(...) \ - do { \ - if (!(__VA_ARGS__)) { \ - std::cerr << "Assertion `" #__VA_ARGS__ "` failed in " << __FILE__ << " line " << __LINE__ << std::endl; \ - std::terminate(); \ - } \ - } while (false) - #else - #define sol_c_assert(...) \ - do { \ - if (false) { \ - (void)(__VA_ARGS__); \ - } \ - } while (false) - #endif -#endif - -#if SOL_IS_ON(SOL_USER_M_ASSERT_I_) - #define sol_m_assert(message, ...) SOL_M_ASSERT(message, __VA_ARGS__) -#else - #if SOL_IS_ON(SOL_DEBUG_BUILD_I_) - #include - #include - #include - - #define sol_m_assert(message, ...) \ - do { \ - if (!(__VA_ARGS__)) { \ - std::cerr << "Assertion `" #__VA_ARGS__ "` failed in " << __FILE__ << " line " << __LINE__ << ": " << message << std::endl; \ - std::terminate(); \ - } \ - } while (false) - #else - #define sol_m_assert(message, ...) \ - do { \ - if (false) { \ - (void)(__VA_ARGS__); \ - (void)sizeof(message); \ - } \ - } while (false) - #endif -#endif - -// clang-format on - -#endif // SOL_ASSERT_HPP +// sol2 + +// The MIT License (MIT) + +// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#pragma once + +#ifndef SOL_ASSERT_HPP +#define SOL_ASSERT_HPP + +#include + +#if SOL_IS_ON(SOL2_CI_I_) + +struct pre_main { + pre_main() { +#ifdef _MSC_VER + _set_abort_behavior(0, _WRITE_ABORT_MSG); +#endif + } +} inline sol2_ci_dont_lock_ci_please = {}; + +#endif // Prevent lockup when doing Continuous Integration + + +// clang-format off + +#if SOL_IS_ON(SOL_USER_C_ASSERT_I_) + #define sol_c_assert(...) SOL_C_ASSERT(__VA_ARGS__) +#else + #if SOL_IS_ON(SOL_DEBUG_BUILD_I_) + #include + #include + #include + + #define sol_c_assert(...) \ + do { \ + if (!(__VA_ARGS__)) { \ + std::cerr << "Assertion `" #__VA_ARGS__ "` failed in " << __FILE__ << " line " << __LINE__ << std::endl; \ + std::terminate(); \ + } \ + } while (false) + #else + #define sol_c_assert(...) \ + do { \ + if (false) { \ + (void)(__VA_ARGS__); \ + } \ + } while (false) + #endif +#endif + +#if SOL_IS_ON(SOL_USER_M_ASSERT_I_) + #define sol_m_assert(message, ...) SOL_M_ASSERT(message, __VA_ARGS__) +#else + #if SOL_IS_ON(SOL_DEBUG_BUILD_I_) + #include + #include + #include + + #define sol_m_assert(message, ...) \ + do { \ + if (!(__VA_ARGS__)) { \ + std::cerr << "Assertion `" #__VA_ARGS__ "` failed in " << __FILE__ << " line " << __LINE__ << ": " << message << std::endl; \ + std::terminate(); \ + } \ + } while (false) + #else + #define sol_m_assert(message, ...) \ + do { \ + if (false) { \ + (void)(__VA_ARGS__); \ + (void)sizeof(message); \ + } \ + } while (false) + #endif +#endif + +// clang-format on + +#endif // SOL_ASSERT_HPP diff --git a/extern/sol3/sol/base_traits.hpp b/extern/sol3/sol/base_traits.hpp index 9fae18e2b0..a28f23a74c 100644 --- a/extern/sol3/sol/base_traits.hpp +++ b/extern/sol3/sol/base_traits.hpp @@ -1,123 +1,123 @@ -// sol2 - -// The MIT License (MIT) - -// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors - -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -#ifndef SOL_BASE_TRAITS_HPP -#define SOL_BASE_TRAITS_HPP - -#include - -namespace sol { - namespace detail { - struct unchecked_t { }; - const unchecked_t unchecked = unchecked_t {}; - } // namespace detail - - namespace meta { - using sfinae_yes_t = std::true_type; - using sfinae_no_t = std::false_type; - - template - using void_t = void; - - template - using unqualified = std::remove_cv>; - - template - using unqualified_t = typename unqualified::type; - - namespace meta_detail { - template - struct unqualified_non_alias : unqualified { }; - - template