diff --git a/apps/essimporter/converter.hpp b/apps/essimporter/converter.hpp index 11f966446..b05337aea 100644 --- a/apps/essimporter/converter.hpp +++ b/apps/essimporter/converter.hpp @@ -271,23 +271,34 @@ private: class ConvertPCDT : public Converter { public: - ConvertPCDT() : mFirstPersonCam(true) {} + ConvertPCDT() + : mFirstPersonCam(true), + mTeleportingEnabled(true), + mLevitationEnabled(true) + {} virtual void read(ESM::ESMReader &esm) { PCDT pcdt; pcdt.load(esm); - convertPCDT(pcdt, mContext->mPlayer, mContext->mDialogueState.mKnownTopics, mFirstPersonCam); + convertPCDT(pcdt, mContext->mPlayer, mContext->mDialogueState.mKnownTopics, mFirstPersonCam, mTeleportingEnabled, mLevitationEnabled, mContext->mControlsState); } virtual void write(ESM::ESMWriter &esm) { + esm.startRecord(ESM::REC_ENAB); + esm.writeHNT("TELE", mTeleportingEnabled); + esm.writeHNT("LEVT", mLevitationEnabled); + esm.endRecord(ESM::REC_ENAB); + esm.startRecord(ESM::REC_CAM_); esm.writeHNT("FIRS", mFirstPersonCam); esm.endRecord(ESM::REC_CAM_); } private: bool mFirstPersonCam; + bool mTeleportingEnabled; + bool mLevitationEnabled; }; class ConvertCNTC : public Converter diff --git a/apps/essimporter/convertplayer.cpp b/apps/essimporter/convertplayer.cpp index 55aaad1c5..9d82af022 100644 --- a/apps/essimporter/convertplayer.cpp +++ b/apps/essimporter/convertplayer.cpp @@ -5,7 +5,7 @@ namespace ESSImport { - void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector& outDialogueTopics, bool& firstPersonCam) + void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector& outDialogueTopics, bool& firstPersonCam, bool& teleportingEnabled, bool& levitationEnabled, ESM::ControlsState& controls) { out.mBirthsign = pcdt.mBirthsign; out.mObject.mNpcStats.mBounty = pcdt.mBounty; @@ -25,18 +25,28 @@ namespace ESSImport out.mObject.mNpcStats.mSkills[i].mProgress = pcdt.mPNAM.mSkillProgress[i]; out.mObject.mNpcStats.mLevelProgress = pcdt.mPNAM.mLevelProgress; - if (pcdt.mPNAM.mDrawState & PCDT::DrawState_Weapon) + if (pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_WeaponDrawn) out.mObject.mCreatureStats.mDrawState = 1; - if (pcdt.mPNAM.mDrawState & PCDT::DrawState_Spell) + if (pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_SpellDrawn) out.mObject.mCreatureStats.mDrawState = 2; - firstPersonCam = !(pcdt.mPNAM.mCameraFlags & PCDT::CameraFlag_ThirdPerson); + firstPersonCam = !(pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_ThirdPerson); + teleportingEnabled = !(pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_TeleportingDisabled); + levitationEnabled = !(pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_LevitationDisabled); for (std::vector::const_iterator it = pcdt.mKnownDialogueTopics.begin(); it != pcdt.mKnownDialogueTopics.end(); ++it) { outDialogueTopics.push_back(Misc::StringUtils::lowerCase(*it)); } + + controls.mViewSwitchDisabled = pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_ViewSwitchDisabled; + controls.mControlsDisabled = pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_ControlsDisabled; + controls.mJumpingDisabled = pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_JumpingDisabled; + controls.mLookingDisabled = pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_LookingDisabled; + controls.mVanityModeDisabled = pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_VanityModeDisabled; + controls.mWeaponDrawingDisabled = pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_WeaponDrawingDisabled; + controls.mSpellDrawingDisabled = pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_SpellDrawingDisabled; } } diff --git a/apps/essimporter/convertplayer.hpp b/apps/essimporter/convertplayer.hpp index f6731eed7..1d2fdc87a 100644 --- a/apps/essimporter/convertplayer.hpp +++ b/apps/essimporter/convertplayer.hpp @@ -4,11 +4,12 @@ #include "importplayer.hpp" #include +#include namespace ESSImport { - void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector& outDialogueTopics, bool& firstPersonCam); + void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector& outDialogueTopics, bool& firstPersonCam, bool& teleportingEnabled, bool& levitationEnabled, ESM::ControlsState& controls); } diff --git a/apps/essimporter/importer.cpp b/apps/essimporter/importer.cpp index f17db309f..1c255c56f 100644 --- a/apps/essimporter/importer.cpp +++ b/apps/essimporter/importer.cpp @@ -422,6 +422,10 @@ namespace ESSImport writer.startRecord (ESM::REC_DIAS); context.mDialogueState.save(writer); writer.endRecord(ESM::REC_DIAS); + + writer.startRecord(ESM::REC_INPU); + context.mControlsState.save(writer); + writer.endRecord(ESM::REC_INPU); } diff --git a/apps/essimporter/importercontext.hpp b/apps/essimporter/importercontext.hpp index c93dff269..fde247ebf 100644 --- a/apps/essimporter/importercontext.hpp +++ b/apps/essimporter/importercontext.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include "importnpcc.hpp" #include "importcrec.hpp" @@ -32,6 +33,8 @@ namespace ESSImport ESM::DialogueState mDialogueState; + ESM::ControlsState mControlsState; + // cells which should show an explored overlay on the global map std::set > mExploredCells; diff --git a/apps/essimporter/importplayer.hpp b/apps/essimporter/importplayer.hpp index 3baab1cd8..9f6b055c0 100644 --- a/apps/essimporter/importplayer.hpp +++ b/apps/essimporter/importplayer.hpp @@ -38,14 +38,20 @@ struct PCDT std::vector mKnownDialogueTopics; - enum DrawState_ + enum PlayerFlags { - DrawState_Weapon = 0x80, - DrawState_Spell = 0x100 - }; - enum CameraFlags - { - CameraFlag_ThirdPerson = 0x2 + PlayerFlags_ViewSwitchDisabled = 0x1, + PlayerFlags_ControlsDisabled = 0x4, + PlayerFlags_WeaponDrawn = 0x80, + PlayerFlags_SpellDrawn = 0x100, + PlayerFlags_JumpingDisabled = 0x1000, + PlayerFlags_LookingDisabled = 0x2000, + PlayerFlags_VanityModeDisabled = 0x4000, + PlayerFlags_WeaponDrawingDisabled = 0x8000, + PlayerFlags_SpellDrawingDisabled = 0x10000, + PlayerFlags_ThirdPerson = 0x20000, + PlayerFlags_TeleportingDisabled = 0x40000, + PlayerFlags_LevitationDisabled = 0x80000 }; #pragma pack(push) @@ -62,8 +68,7 @@ struct PCDT struct PNAM { - short mDrawState; // DrawState - short mCameraFlags; // CameraFlags + int mPlayerFlags; // controls, camera and draw state unsigned int mLevelProgress; float mSkillProgress[27]; // skill progress, non-uniform scaled unsigned char mSkillIncreases[8]; // number of skill increases for each attribute diff --git a/apps/openmw/mwbase/inputmanager.hpp b/apps/openmw/mwbase/inputmanager.hpp index 75c55e028..0eb06ee3d 100644 --- a/apps/openmw/mwbase/inputmanager.hpp +++ b/apps/openmw/mwbase/inputmanager.hpp @@ -5,6 +5,19 @@ #include #include +#include + +namespace Loading +{ + class Listener; +} + +namespace ESM +{ + class ESMReader; + class ESMWriter; +} + namespace MWBase { /// \brief Interface for input manager (implemented in MWInput) @@ -56,6 +69,10 @@ namespace MWBase /// Returns if the last used input device was a joystick or a keyboard /// @return true if joystick, false otherwise virtual bool joystickLastUsed() = 0; + + virtual int countSavedGameRecords() const = 0; + virtual void write(ESM::ESMWriter& writer, Loading::Listener& progress) = 0; + virtual void readRecord(ESM::ESMReader& reader, uint32_t type) = 0; }; } diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 6c2e695e6..2f49d3463 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -16,6 +16,9 @@ #include #include +#include +#include +#include #include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" @@ -1574,6 +1577,44 @@ namespace MWInput mInputBinder->removeJoystickButtonBinding (mFakeDeviceID, mInputBinder->getJoystickButtonBinding (control, mFakeDeviceID, ICS::Control::INCREASE)); } + int InputManager::countSavedGameRecords() const + { + return 1; + } + + void InputManager::write(ESM::ESMWriter& writer, Loading::Listener& /*progress*/) + { + ESM::ControlsState controls; + controls.mViewSwitchDisabled = !getControlSwitch("playerviewswitch"); + controls.mControlsDisabled = !getControlSwitch("playercontrols"); + controls.mJumpingDisabled = !getControlSwitch("playerjumping"); + controls.mLookingDisabled = !getControlSwitch("playerlooking"); + controls.mVanityModeDisabled = !getControlSwitch("vanitymode"); + controls.mWeaponDrawingDisabled = !getControlSwitch("playerfighting"); + controls.mSpellDrawingDisabled = !getControlSwitch("playermagic"); + + writer.startRecord (ESM::REC_INPU); + controls.save(writer); + writer.endRecord (ESM::REC_INPU); + } + + void InputManager::readRecord(ESM::ESMReader& reader, uint32_t type) + { + if (type == ESM::REC_INPU) + { + ESM::ControlsState controls; + controls.load(reader); + + toggleControlSwitch("playerviewswitch", !controls.mViewSwitchDisabled); + toggleControlSwitch("playercontrols", !controls.mControlsDisabled); + toggleControlSwitch("playerjumping", !controls.mJumpingDisabled); + toggleControlSwitch("playerlooking", !controls.mLookingDisabled); + toggleControlSwitch("vanitymode", !controls.mVanityModeDisabled); + toggleControlSwitch("playerfighting", !controls.mWeaponDrawingDisabled); + toggleControlSwitch("playermagic", !controls.mSpellDrawingDisabled); + } + } + void InputManager::resetToDefaultKeyBindings() { loadKeyDefaults(true); diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 644391688..8809f44cd 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -149,6 +149,10 @@ namespace MWInput void clearAllKeyBindings (ICS::Control* control); void clearAllControllerBindings (ICS::Control* control); + virtual int countSavedGameRecords() const; + virtual void write(ESM::ESMWriter& writer, Loading::Listener& progress); + virtual void readRecord(ESM::ESMReader& reader, uint32_t type); + private: SDL_Window* mWindow; bool mWindowVisible; diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp index 48cc37935..58d85fe5b 100644 --- a/apps/openmw/mwstate/statemanagerimp.cpp +++ b/apps/openmw/mwstate/statemanagerimp.cpp @@ -249,7 +249,8 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot +MWBase::Environment::get().getScriptManager()->getGlobalScripts().countSavedGameRecords() +MWBase::Environment::get().getDialogueManager()->countSavedGameRecords() +MWBase::Environment::get().getWindowManager()->countSavedGameRecords() - +MWBase::Environment::get().getMechanicsManager()->countSavedGameRecords(); + +MWBase::Environment::get().getMechanicsManager()->countSavedGameRecords() + +MWBase::Environment::get().getInputManager()->countSavedGameRecords(); writer.setRecordCount (recordCount); writer.save (stream); @@ -271,6 +272,7 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot MWBase::Environment::get().getScriptManager()->getGlobalScripts().write (writer, listener); MWBase::Environment::get().getWindowManager()->write(writer, listener); MWBase::Environment::get().getMechanicsManager()->write(writer, listener); + MWBase::Environment::get().getInputManager()->write(writer, listener); // Ensure we have written the number of records that was estimated if (writer.getRecordCount() != recordCount+1) // 1 extra for TES3 record @@ -462,6 +464,10 @@ void MWState::StateManager::loadGame (const Character *character, const std::str MWBase::Environment::get().getMechanicsManager()->readRecord(reader, n.intval); break; + case ESM::REC_INPU: + MWBase::Environment::get().getInputManager()->readRecord(reader, n.intval); + break; + default: // ignore invalid records diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index d6063c230..51faaba1d 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -77,7 +77,7 @@ add_component_dir (esm loadweap records aipackage effectlist spelllist variant variantimp loadtes3 cellref filter savedgame journalentry queststate locals globalscript player objectstate cellid cellstate globalmap inventorystate containerstate npcstate creaturestate dialoguestate statstate npcstats creaturestats weatherstate quickkeys fogstate spellstate activespells creaturelevliststate doorstate projectilestate debugprofile - aisequence magiceffects util custommarkerstate stolenitems transport animationstate + aisequence magiceffects util custommarkerstate stolenitems transport animationstate controlsstate ) add_component_dir (esmterrain diff --git a/components/esm/controlsstate.cpp b/components/esm/controlsstate.cpp new file mode 100644 index 000000000..ae4e1dff1 --- /dev/null +++ b/components/esm/controlsstate.cpp @@ -0,0 +1,43 @@ +#include "controlsstate.hpp" + +#include "esmreader.hpp" +#include "esmwriter.hpp" + +ESM::ControlsState::ControlsState() + : mViewSwitchDisabled(false), + mControlsDisabled(false), + mJumpingDisabled(false), + mLookingDisabled(false), + mVanityModeDisabled(false), + mWeaponDrawingDisabled(false), + mSpellDrawingDisabled(false) +{ +} + +void ESM::ControlsState::load(ESM::ESMReader& esm) +{ + int flags; + esm.getHNT(flags, "CFLG"); + + mViewSwitchDisabled = flags & ViewSwitchDisabled; + mControlsDisabled = flags & ControlsDisabled; + mJumpingDisabled = flags & JumpingDisabled; + mLookingDisabled = flags & LookingDisabled; + mVanityModeDisabled = flags & VanityModeDisabled; + mWeaponDrawingDisabled = flags & WeaponDrawingDisabled; + mSpellDrawingDisabled = flags & SpellDrawingDisabled; +} + +void ESM::ControlsState::save(ESM::ESMWriter& esm) const +{ + int flags = 0; + if (mViewSwitchDisabled) flags |= ViewSwitchDisabled; + if (mControlsDisabled) flags |= ControlsDisabled; + if (mJumpingDisabled) flags |= JumpingDisabled; + if (mLookingDisabled) flags |= LookingDisabled; + if (mVanityModeDisabled) flags |= VanityModeDisabled; + if (mWeaponDrawingDisabled) flags |= WeaponDrawingDisabled; + if (mSpellDrawingDisabled) flags |= SpellDrawingDisabled; + + esm.writeHNT("CFLG", flags); +} diff --git a/components/esm/controlsstate.hpp b/components/esm/controlsstate.hpp new file mode 100644 index 000000000..b9654ea1a --- /dev/null +++ b/components/esm/controlsstate.hpp @@ -0,0 +1,39 @@ +#ifndef OPENMW_ESM_CONTROLSSTATE_H +#define OPENMW_ESM_CONTROLSSTATE_H + +namespace ESM +{ + class ESMReader; + class ESMWriter; + + // format 0, saved games only + + struct ControlsState + { + ControlsState(); + + enum Flags + { + ViewSwitchDisabled = 0x1, + ControlsDisabled = 0x4, + JumpingDisabled = 0x1000, + LookingDisabled = 0x2000, + VanityModeDisabled = 0x4000, + WeaponDrawingDisabled = 0x8000, + SpellDrawingDisabled = 0x10000 + }; + + bool mViewSwitchDisabled; + bool mControlsDisabled; + bool mJumpingDisabled; + bool mLookingDisabled; + bool mVanityModeDisabled; + bool mWeaponDrawingDisabled; + bool mSpellDrawingDisabled; + + void load (ESMReader &esm); + void save (ESMWriter &esm) const; + }; +} + +#endif diff --git a/components/esm/defs.hpp b/components/esm/defs.hpp index 8066b622a..0f0478faa 100644 --- a/components/esm/defs.hpp +++ b/components/esm/defs.hpp @@ -127,6 +127,7 @@ enum RecNameInts REC_ENAB = FourCC<'E','N','A','B'>::value, REC_CAM_ = FourCC<'C','A','M','_'>::value, REC_STLN = FourCC<'S','T','L','N'>::value, + REC_INPU = FourCC<'I','N','P','U'>::value, // format 1 REC_FILT = FourCC<'F','I','L','T'>::value,